IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 2021-08-15 -> 正文阅读

[数据结构与算法]2021-08-15

考研初试算法题合集1线性表与链表

算法书上的代码都是伪代码,为了便于记忆,参考着资料实现了一遍,一切为了理解。

#include <iostream>
#include <stdio.h>
#include<stdlib.h>
#include<mm_malloc.h>
using namespace std;
typedef int Status;
#define ElemType int //此处将抽象数据类型定义为int
#define error 0//达不到目标要求则返回0
#define OK 1 //程序执行成功时返回1
#define LISTINCREAMENT 10//定义线性表扩容空间
#define OVERFLOW -2//宏定义溢出
typedef struct sqlist{
    ElemType *elem;//定义了一个指向ElemType类型的指针elem
    int listsize;//线性表最大表长
    int length;//线性表实际长度
}Sqlist;


//顺序表插入
Status ListInsert_Sq(Sqlist &L,int i,ElemType x)
{
    ElemType *newbase,*p,*q;
    if(i<1||i>L.length+1) return error;
    if(L.length>=L.listsize)//空间不足需要扩展
    {
        newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREAMENT)*sizeof(ElemType));
        if(!newbase)exit(OVERFLOW);//申请不到内存,程序结束
        L.elem=newbase;//成功申请内存,将线性表的首地址放到新申请到的内存上
        L.listsize+=LISTINCREAMENT;//修改线性表的最大长度
    }//if后为增强健壮性语句可不写
    q=&(L.elem[i-1]);//q指针指向要插入的位置
    for(p=&(L.elem[L.length-1]);p>=q;--p)
        *(p+1)=*p;//从插入位置开始所有元素向后移动一位
    *q=x;//插入待插入元素
    L.length++;//线性表长度加一
    return OK;
}


//顺序表删除
Status ListDelete_sq(Sqlist &L,int i,ElemType &e)
{
    ElemType *p,*q;
    if((i<1)||(i>L.length))return error;
    p=&(L.elem[i]);
    e=*p;
    q=L.elem+L.length-1;
    for(++p;p<=q;++p)
        *(p-1)=*p;
    --L.length;
}//ListDelete_sq


//顺序表合并
void MergeList_Sq(Sqlist La,Sqlist Lb,Sqlist &Lc)
//已知顺序线性表La和Lb的元素按值非递减排列
//归并La和Lb得到的新顺序表Lc,使Lc也按照非递减元素排列
{
    ElemType *pa,*pb,*pc,*pa_last,*pb_last;
    pa=La.elem;//指针pa指向线性表La的首地址
    pb=Lb.elem;//指针pb指向线性表Lb的首地址
    Lc.listsize=Lc.length=La.length+Lb.length;//Lc需要申请的内存空间,等于合并表Lc的长度,等于表La的长度与Lb的长度之和
    pc=Lc.elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType));//为Lc申请内存空间,同时将指针pc指向Lc
    if(!Lc.elem)exit(OVERFLOW);//无可用的内存空间时退出程序
    pa_last=La.elem+La.length-1;//使指针Pa_last指向pa的最后一个元素
    pb_last=Lb.elem+Lb.length-1;//使指针Pb_last指向pa的最后一个元素
    while(pa<=pa_last&&pb<=pb_last)//便利条件为两个线性表都还没有便历完
    {
        if(*pa<*pb) //哪个表中的元素比较小先把哪个表中的元素插入
            *pc++=*pa++;
        else
            *pc++=*pb++;
    }
    //由于两个表长度不一定相同,遍历后会剩一个未便历完表,将剩余表中的元素插入Lc
    while(pa<=pa_last)*pc++=*pa++;
    while(pb<=pb_last)*pc++=*pb++;
}//MergeList_Sq


//单链表结点结构
typedef struct Lnode{
    ElemType data;
    struct Lnode *next;
}Lnode,*LinkList;//此处定义指针类型的两种形式 使用Lnode定义时需要在被定义指针名称前加*,LinkList直接使用即可。

//单链表查找第i个元素
Status GetElem_L(LinkList L,int i,ElemType &e)
{
    //L是带头节点的单链表的头指针
    //第i个元素存在时将该元素值赋给e并返回OK,否则返回error
    LinkList p;//Lnode *p;
    p=L->next;int k=1; //初始化,p指向第一个节点,k为计数器
    while(p&&k<i)//顺时针向后查找,直到p指向第i个元素或者p为空
    {
        p=p->next;
        ++k;
    }
    if(!p||k>i)//第i个元素不存在
        return error;
    e=p->data;
    return OK;
}

//单链表的插入算法
Status ListInsert(LinkList &L,int i,ElemType e)
{
    //在带头节点的单链表L中的第i的元素之前插入e
    Lnode *p,*s;//p指针用来遍历,s指针用来插入赋值
    p=L; int k=0;//初始化,p指向头节点,k为计数器
    while(p&&k<i-1)//逐步移向p,直到P指向第i-1个元素或P为空
    {
        p=p->next;//
        ++k;
    }
    if(!p||k>i-1)
        return error;//无法插入
    if(!(s=(LinkList)malloc(sizeof(Lnode))));//申请元素e的结点空间
    return OVERFLOW;//内存无空闲单元
    s->data=e;
    s->next=p->next;//插入元素e的结点
    p->next=s;//
    return OK;
}//ListInsert_L

//单链表的删除操作
Status ListDelete_L(LinkList &L,int i,ElemType &e)
{
    //在带头结点的线性单链表L中,删除第i个元素,并由e返回其值
    Lnode *p,*q;
    p=L; int j=0;
    while(p->next&&j<i-1)//p指针作为用来遍历的移动指针,最终指向第i-1个元素
    {
        p=p->next;
        j++;
    }
    if(!(p->next)||j>i-1)//删除位置不合理
        return error;
    q=p->next;
    p->next=q->next;
    e=q->data;free(q);//删除并释放结点
    return OK;
}

//表头插入法建立单链表(无头节点)
void Create_L(LinkList &L,int n)
{
    Lnode *p;//此处用自由结点把输入的值一个一个插入链表中
    L=(LinkList)malloc(sizeof(Lnode));
    L->next=NULL;//始终保持第一个结点为空
    for(int i=n;i>0;--i)
    {
        p=(LinkList)malloc(sizeof(Lnode));//初始化结点
        scanf("%d",&p->data);
        p->next=L->next;L->next=p;//从后向前插入结点
    }
}


//表尾插入法建立不带头节点的链表
LinkList CreateL1()
{
    LinkList h;
    h = (LinkList)malloc(sizeof(Lnode));//初始化指针h始终指向第一个节点
    LinkList p,r;//p为移动指针,r始终指向表尾,为表尾指针
    r=h;//初始时表头即表尾
    int n;//使用数字n来输入,也可先初始化一遍p结点,直接在while循环中输入p结点的值
    while(scanf("%d",&n)!=EOF)
    {
        p=(Lnode*)malloc(sizeof(Lnode));//每次将移动结点初始化,以便进行下一次赋值
        p->data=n;
        r->next=p;
        r=p;
    }
    r->next=NULL;//待所有节点插入完成后,将尾结点置空
    return h;//返回表头指针所指地址
}

//有序单链表合并
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)
{
    Lnode *pa,*pb,*pc;//创立移动结点pa,pb,pc
    pa=La->next;//pa指向La的第一个节点
    pb=Lb->next;//pb指向Lb的第一个节点
    while(pa&&pb){//遍历结束条件为pa与pb都不为空
        if(pa->data<=pb->data){//哪个结点小先插入哪个节点
            pc->next=pa;
            pc=pa;
            pa=pa->next;//插入一个结点后,相应链表的移动指针后移一位
        }
        else {
            pc->next=pb;
            pc=pb;
            pb=pb->next;
        }
    }//while
    pc->next=pa?pa:pb;//将最后剩的链表插入Lc中
    free(Lb);
}//MergeList_L

//约瑟夫环
#include<iostream>
using namespace std;
const int N=20;
typedef struct node{//定义一个双向链表
    int id;
    struct node *next;//后继指针
    struct node *pre;//前驱指针
}Node,*pNode;
pNode RingConstruct(int n)
{
    int i;
    pNode h,p,q;//h作为头指针,p作为尾指针,q作为输入元素的指针
    h=(pNode)malloc(sizeof(Node));//初始化第一个结点
    h->id=1;//给第一个结点编号
    p=h;//初始时表头即表尾
    for(i=2;i<=n;i++)
    {
        q=(pNode)malloc(sizeof(Node));//对每个要插入的结点进行初始化
        q->id=i;//对每个插入结点编号
        p->next=q;//表尾结点的的后继指针指向要插入的结点
        q->pre=p;//要插入结点的前驱指针指向上一个结点
        p=p->next;//表尾指针转而指向新插入的结点
    }
    p->next=h;
    h->pre=p;//最后衔接表头表尾,完成循环链表
    return h;
}
int boundMachine(int order){
    int boundList[4]={3,5,7,13};
    return boundList[(order-1)%4];
}
pNode count(pNode first,int bound){
    //返回当前趟起始结点,bond参数由boundMachine提供
    pNode q;
    q=first;
    for(int i=2;i<=bound;i++){
        q=q->next;
    }
    return q;
}
//将currentNode从环中删除,并返回被删除的下一结点
pNode removeNode(pNode currentNode)
{
    pNode first = currentNode->next;//当前删除结点的后继是下一趟的起始结点
    first->pre=currentNode->pre;
    cout<<currentNode->id<<"";
    free(currentNode);
    return first;
}
int main(){
    pNode first,toRemove;//first为每一趟的起始结点,toRemove为要删除的结点,通过函数removeNode提供下一趟起始地址
    int i;
    first=RingConstruct(N);
    for(int i=1;i<=N;i++){
        toRemove=count(first, boundMachine(i));
        first=removeNode(toRemove);
    }
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 11:59:24  更:2021-08-16 12:01:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 17:22:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计