花了好几个小时,详细规划出了整个过程,包括所有基本操作。。。有什么疑问请下方留言
#include<iostream> using namespace std; #define ElemType char #define ERROR 0 #define OK 1 typedef struct Node { ElemType data; struct Node *next; }Node,*LinkList; void init_linklist(LinkList L)/*对单链表进行初始化*/ { L=(Node*)malloc(sizeof(Node)); /*申请结点空间*/ L->next=NULL; /*置为空表*/ } void CreateFromHead(LinkList L) { Node *s; char c; int flag=1,k=0; while(flag) /* flag初值为1,当输入"$"时,置flag为0,建表结束*/ { c=getchar(); if(c!='$') { s=(LinkList)malloc(sizeof(Node)); /*建立新结点s*/ s->data=c; s->next=L->next;/*将s结点插入表头*/ L->next=s; if(k==0) {k=1;s->next=NULL;} //具体为啥不知道,但数据结构课程源程序的确是的结尾指向不为空,通过k标记,使得结尾为空 } else flag=0; } } void CreateFromTail(LinkList L) { Node *r, *s; char c; int flag =1; /*设置一个标志,初值为1,当输入"$"时,flag为0,建表结束*/ r=L; /*r指针动态指向链表的当前表尾,以便于做尾插入,其初值指向头结点*/ while(flag) /*循环输入表中元素值,将建立新结点s插入表尾*/ { c=getchar(); if(c!='$') { s=(Node*)malloc(sizeof(Node)); s->data=c; r->next=s; r=s; } else { flag=0; r->next=NULL; /*将最后一个结点的next链域置为空,表示链表的结束*/ } } } ElemType Get (LinkList L, int i) /*在带头结点的单链表L中查找第i个结点,若找到(1≤i≤n),则返回该结点的存储数值; */ { int j; Node *p; p=L; j=0; /*从头结点开始扫描*/ while ((p->next!=NULL)&&(j<i)) { p=p->next; /* 扫描下一结点*/ j++; /* 已扫描结点计数器 */ } if(i == j) return p->data; /* 找到了第i个结点 */ else return NULL; /* 找不到,i≤0或i>n */ } int Locate( LinkList L,ElemType key) /*在带头结点的单链表L中查找其结点值等于key的结点,若找到则返回该结点的位置p,否则返回NULL*/ { Node *p; int k=1; p=L->next; /*从表中第一个结点开始 */ while (p!=NULL) { if (p->data!=key) p=p->next; else break; /*找到结点值=key时退出循环 */ k++; } return k; } int ListLength(LinkList L) /*求带头结点的单链表L的长度*/ { Node *p; int j; p=L->next; j=0; /*用来存放单链表的长度*/ while(p!=NULL) { p=p->next; j++; } return j; /*j为求得的单链表长度*/ } int InsList(LinkList L,int i,ElemType e) /*在带头结点的单链表L中第i个位置插入值为e的新结点*/ { Node *pre,*s; int k; if(i<=0)return ERROR; pre=L; k=0; /*从"头"开始,查找第i-1个结点*/ while(pre!=NULL&&k<i-1) /*表未查完且未查到第i-1个时重复,找到pre指向第i-1个*/ { pre=pre->next; k=k+1; } /*查找第i-1结点*/ if(!pre) /*如当前位置pre为空表已找完还未数到第i个,说明插入位置不合理*/ { printf("插入位置不合理!"); return ERROR; } s=(Node*)malloc(sizeof(Node)); /*申请一个新的结点S */ s->data=e; /*值e置入s的数据域*/ s->next=pre->next; /*修改指针,完成插入操作*/ pre->next=s; return OK; } int DelList(LinkList L,int i,ElemType *e) /*在带头结点的单链表L中删除第i个元素,并将删除的元素保存到变量*e中*/ { Node *pre,*r; int k; pre=L; k=0; while(pre->next!=NULL && k<i-1) /*寻找被删除结点i的前驱结点i-1使p指向它*/ { pre=pre->next; k=k+1; } /*查找第i-1个结点*/ if(!(pre->next)) /* 即while循环是因为p->next=NULL或i<1而跳出的,而是因为没有找到合法的前驱位置,说明删除位置i不合法。*/ { printf("删除结点的位置i不合理!"); return ERROR; } r=pre->next; pre->next=pre->next->next; /*修改指针,删除结点r*/ *e = r->data; free(r); /*释放被删除的结点所占的内存空间*/ printf("成功删除结点!"); return OK; } LinkList MergeLinkList(LinkList LA, LinkList LB) /*将递增有序的单链表LA和LB合并成一个递增有序的单链表LC*/ { Node *pa,*pb; Node *r; LinkList LC; /*将LC初始置空表。pa和pb分别指向两个单链表LA和LB中的第一个结点,r初值为LC*/ pa=LA->next; pb=LB->next; LC=LA; LC->next=NULL; r=LC; /*当两个表中均未处理完时,比较选择将较小值结点插入到新表LC中。*/ while(pa!=NULL && pb!=NULL) { if(pa->data <= pb->data) { r->next=pa; r=pa; pa=pa->next; } else { r->next=pb; r=pb; pb=pb->next; } } if(pa) /*若表LA未完,将表LA中后续元素链到新表LC表尾*/ r->next=pa; else /*否则将表LB中后续元素链到新表LC表尾*/ r->next=pb; // free(LB); 原文是这么写的,不过释放失败,原因请看我的博客"浅析C语言malloc与free" return(LC); } void print(LinkList L) { LinkList p=L->next; int i=0; while(p!=NULL) { cout<<p->data<<" "; p=p->next; } cout<<endl; } int main() { Node LA,LB; LinkList LC; int n; ElemType key; init_linklist(&LA); init_linklist(&LB); cout<<"以尾插法建立链表LB:(输入$结束)"<<endl; CreateFromTail(&LA); print(&LA); cout<<"以头插法建立链表LB:(输入$结束)"<<endl; CreateFromHead(&LB); print(&LB); cout<<"在LA中按序号查找某元素输出值"<<endl; cin>>n; cout<<Get (&LA,n)<<endl; cout<<"在LA中按值查找某元素输出序号"<<endl; cin>>key; cout<<Locate(&LA,key)<<endl; cout<<"求LA表的节点长度:"<<endl; cout<<ListLength(&LA)<<endl; cout<<"在LA表中插入数e(输入位置和e,注意此时的ElemType是char类型,最大支持读入9)"<<endl; cin>>n; cin>>key; if(InsList(&LA,n,key)) { cout<<"插入成功!"<<endl; print(&LA); } else cout<<"插入失败!"<<endl; cout<<"在LA表中删除第i个元素(输入位置i)"<<endl; cin>>n; if(DelList(&LA,n,&key)) cout<<"删除的元素为:"<<key<<endl; else cout<<"删除失败!"<<endl; cout<<"合并LA,LB后的链表为:"<<endl; LC=MergeLinkList(&LA,&LB); print(LC); return 0; }
附带:循环链表的合并算法
LinkList merge_1(LinkList LA,LinkList LB) { /*此算法将两个采用头指针的循环单链表的首尾连接起来*/ Node *p, *q; p=LA; q=LB; while (p->next!=LA) p=p->next; /*找到表LA的表尾,用p指向它*/ while (q->next!=LB) q=q->next; /*找到表LB的表尾,用q指向它*/ q->next=LA; /*修改表LB 的尾指针,使之指向表LA 的头结点*/ p->next=LB->next; /*修改表LA的尾指针,使之指向表LB 中的第一个结点*/ free(LB); return(LA); } LinkList merge_2(LinkList RA,LinkList RB) { /*此算法将两个采用尾指针的循环链表首尾连接起来*/ Node *p; p=RA->next; /*保存链表RA的头结点地址*/ RA->next=RB->next->next;/*链表RB的开始结点链到链表RA的终端结点之后*/ free(RB->next);/*释放链表RB的头结点*/ RB->next=p;/*链表RA的头结点链到链表RB的终端结点之后*/ return RB;/*返回新循环链表的尾指针*/ }
双向链表的插入与删除
int DlinkIns(DoubleList L,int i,ElemType e) { DNode *s,*p; int k; p=L; k=0; /*从"头"开始,查找第i-1个结点*/ while(p->next!=L&&k<i) /*表未查完且未查到第i-1个时重复,找到p指向第i个*/ { p=p->next; k=k+1; } /*查找第i-1结点*/ if(p->next == L) /*如当前位置p为空表已找完还未数到第i个,说明插入位置不合理*/ { printf("插入位置不合理!"); return ERROR; } s=(DNode*)malloc(sizeof(DNode)); if (s) { s->data=e; s->prior=p->prior; p->prior->next=s; s->next=p; p->prior=s; return OK; } else return ERROR; } int DlinkDel(DoubleList L,int i,ElemType *e) { DNode *p; int k; p=L; k=0; /*从"头"开始,查找第i个结点*/ while(p->next!=L && k<i) /*表未查完且未查到第i个时重复,找到p指向第i个*/ { p=p->next; k=k+1; } if(p->next == L) { return ERROR; } else { *e=p->data; p->prior->next=p->next; p->next->prior=p->prior; free(p); return OK; } }
静态链表的初始化,节点分配&回收
void initial(StaticList space, int *av) { int k; space[0].cursor=0; /*设置已用静态单链表的头指针指向位置0*/ for(k=0;k<Maxsize-1;k++) space[k].cursor=k+1; /*连链*/ space[Maxsize-1].cursor=0; /*标记链尾*/ *av=1; /*设置备用链表头指针初值*/ } int getnode(StaticList space, int *av) /*从备用链表摘下一个结点空间,分配给待插入静态链表中的元素*/ { int i; i=*av; *av=space[*av].cursor; return i; } void freenode(StaticList space, int *av, int k) /*将下标为 k的空闲结点插入到备用链表*/ { space[k].cursor=*av; *av=k; }
时间: 2024-10-09 07:43:29