#include stdio.h #include string.h #include ctype.h #include stdlib.h #include io.h #include math.h #include time.h #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 // 存储空间初始分配量 typedef int Status;// Status是函数的类型,其值是函数结果状态代码,如OK等 typedef int ElemType;//ElemType类型根据实际情况而定,这里假设为int Status visit(ElemType c) { printf(%d ,c); return OK; } typedef struct Node { ElemType data; struct Node *next; }Node; typedef struct Node *LinkList; // 定义LinkList // 初始化顺序线性表 Status InitList(LinkList *L) { *L=(LinkList)malloc(sizeof(Node)); // 产生头结点,并使L指向此头结点 if(!(*L)) // 存储分配失败 return ERROR; (*L)->next=NULL; //指针域为空 return OK; } //初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE Status ListEmpty(LinkList L) { if(L->next) return FALSE; else return TRUE; } // 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 Status ClearList(LinkList *L) { LinkList p,q; p=(*L)->next; // p指向第一个结点 while(p) // 没到表尾 { q=p->next; free(p); p=q; } (*L)->next=NULL; // 头结点指针域为空 return OK; } // 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 int ListLength(LinkList L) { int i=0; LinkList p=L->next; // p指向第一个结点 while(p) { i++; p=p->next; } return i; } //初始条件:顺序线性表L已存在,1≤i≤ListLength(L) //操作结果:用e返回L中第i个数据元素的值 Status GetElem(LinkList L,int i,ElemType *e) { int j; LinkList p; // 声明一结点p p = L->next; // 让p指向链表L的第一个结点 j = 1; // j为计数器 while (p && jnext; // 让p指向下一个结点 ++j; } if ( !p || j>i ) return ERROR; // 第i个元素不存在 *e = p->data; // 取第i个元素的数据 return OK; } // 初始条件:顺序线性表L已存在 // 操作结果:返回L中第1个与e满足关系的数据元素的位序。 //若这样的数据元素不存在,则返回值为0 int LocateElem(LinkList L,ElemType e) { int i=0; LinkList p=L->next; while(p) { i++; if(p->data==e) // 找到这样的数据元素 return i; p=p->next; } return 0; } //初始条件:顺序线性表L已存在,1≤i≤ListLength(L) // 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 Status ListInsert(LinkList *L,int i,ElemType e) { int j; LinkList p,s; p = *L; j = 1; while (p && j < i) // 寻找第i个结点 { p = p->next; ++j; } if (!p || j > i) return ERROR; // 第i个元素不存在 s = (LinkList)malloc(sizeof(Node)); // 生成新结点(C语言标准函数) s->data = e; s->next = p->next; //将p的后继结点赋值给s的后继 p->next = s; //将s赋值给p的后继 return OK; } // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) // 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 Status ListDelete(LinkList *L,int i,ElemType *e) { int j; LinkList p,q; p = *L; j = 1; while (p->next && j < i) // 遍历寻找第i个元素 { p = p->next; ++j; } if (!(p->next) || j > i) return ERROR; //第i个元素不存在 q = p->next; p->next = q->next; //将q的后继赋值给p的后继 *e = q->data; // 将q结点中的数据给e free(q); // 让系统回收此结点,释放内存 return OK; } // 初始条件:顺序线性表L已存在 // 操作结果:依次对L的每个数据元素输出 Status ListTraverse(LinkList L) { LinkList p=L->next; while(p) { visit(p->data); p=p->next; } printf( ); return OK; } // 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) void CreateListHead(LinkList *L, int n) { LinkList p; int i; srand(time(0)); // 初始化随机数种子 *L = (LinkList)malloc(sizeof(Node)); (*L)->next = NULL; // 先建立一个带头结点的单链表 for (i=0; idata = rand()%100+1; // 随机生成100以内的数字 p->next = (*L)->next; (*L)->next = p; // 插入到表头 } } // 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) void CreateListTail(LinkList *L, int n) { LinkList p,r; int i; srand(time(0)); // 初始化随机数种子 *L = (LinkList)malloc(sizeof(Node)); // L为整个线性表 r=*L; // r为指向尾部的结点 for (i=0; idata = rand()%100+1; // 随机生成100以内的数字 r->next=p; // 将表尾终端结点的指针指向新结点 r = p; // 将当前的新结点定义为表尾终端结点 } r->next = NULL; // 表示当前链表结束 } int main() { LinkList L; ElemType e; Status i; int j,k; i=InitList(&L); printf(初始化L后:ListLength(L)=%d ,ListLength(L)); for(j=1;j<=5;j++) i=ListInsert(&L,1,j); printf(在L的表头依次插入1~5后:L.data=); ListTraverse(L); printf(ListLength(L)=%d ,ListLength(L)); i=ListEmpty(L); printf(L是否空:i=%d(1:是 0:否) ,i); i=ClearList(&L); printf(清空L后:ListLength(L)=%d ,ListLength(L)); i=ListEmpty(L); printf(L是否空:i=%d(1:是 0:否) ,i); for(j=1;j<=10;j++) ListInsert(&L,j,j); printf(在L的表尾依次插入1~10后:L.data=); ListTraverse(L); printf(ListLength(L)=%d ,ListLength(L)); ListInsert(&L,1,0); printf(在L的表头插入0后:L.data=); ListTraverse(L); printf(ListLength(L)=%d ,ListLength(L)); GetElem(L,5,&e); printf(第5个元素的值为:%d ,e); for(j=3;j<=4;j++) { k=LocateElem(L,j); if(k) printf(第%d个元素的值为%d ,k,j); else printf(没有值为%d的元素 ,j); } k=ListLength(L); // k为表长 for(j=k+1;j>=k;j--) { i=ListDelete(&L,j,&e); // 删除第j个数据 if(i==ERROR) printf(删除第%d个数据失败 ,j); else printf(删除第%d个的元素值为:%d ,j,e); } printf(依次输出L的元素:); ListTraverse(L); j=5; ListDelete(&L,j,&e); // 删除第5个数据 printf(删除第%d个的元素值为:%d ,j,e); printf(依次输出L的元素:); ListTraverse(L); i=ClearList(&L); printf( 清空L后:ListLength(L)=%d ,ListLength(L)); CreateListHead(&L,20); printf(整体创建L的元素(头插法):); ListTraverse(L); i=ClearList(&L); printf( 删除L后:ListLength(L)=%d ,ListLength(L)); CreateListTail(&L,20); printf(整体创建L的元素(尾插法):); ListTraverse(L); return 0; }
接下来针对两链表求并,求交。
1)【链表反向按序求并】两个按递增次序排列的单链表,编写算法合并,按递减次序排列,并要求利用原来两个单链表的结点存放新的链表。
LinkList Union(LinkList la,lb) { pa=la->next; pb=lb->next;// pa,pb是工作指针 la->next=null;// la为结果链表的头指针 while(la&&lb) { if(pa->data<=pb->data) { r=pa->next;// 将pa的后继暂存于r pa->next=la->next;// 将pa的结果存于结果表中,同时逆置 la->next=pa; pa=r;// 恢复pa为当前待比较结点 } else { r=pb->next;// 将pa的后继暂存于r pb->next=la->next;// 将pb的结果存于结果表中,同时逆置 la->next=pb; pb=r;// 恢复pb为当前待比较结点 } if(pa) pb=pa;// 避免对pa再写如下的while语句 while(pb!=null) { r=pb->next; pb->next=la->next; la->next=pb; pb=r; } } }2) 两链表递增有序,合并后依然有序,但是要求不带重复元素
#include "stdafx.h" #include<iostream> using namespace std; typedef struct node { int data; struct node *next; }Listnode,*LinkList; int _tmain(int argc, _TCHAR* argv[]) { return 0; } void Merge(LinkList &La,LinkList &Lb,LinkList &Lc) { LinkList pa,pb,pc,u; pa=La->next,pb=Lb->next; Lc=pc=La; while(pa&&pb) { if(pa->data<pb->data) { pc->next=pa; pc=pa; pa=pa->next; } else if(pa->data>pb->data) { pc->next=pb; pc=pb; pb=pb->next; } else //关键步,处理相等的元素 { pc->next=pb; pc=pb; pb=pb->next; u=pa; pa=pa->next; free(u); } if(pa)pc->next=pa;else pc->next=pb; free(Lb); } }3)两个带头结点的链表从小到大排序,求两个链表的交集,要求依旧从小到大排序,没有重复元素。
#include "stdafx.h" #include<iostream> using namespace std; typedef struct node { int data; struct node *next; }Listnode,*LinkList; int _tmain(int argc, _TCHAR* argv[]) { return 0; } void Merge(LinkList &La,LinkList &Lb,LinkList &Lc) { LinkList pa,pb,pc,u; pa=La->next,pb=Lb->next; Lc=pc=La; while(pa&&pb) { if(pa->data<pb->data) { u=pa; pa=pa->next; free(u); } else if(pa->data>pb->data) { pb=pb->next; } else { if(pc==La) //处理第一个相等的元素 { pc->next=pa;pc=pa;pa=pa->next; } else if(pc->data==pa->data) //重复元素不进入La表 { u=pa; pa=pa->next;free(u); } else //交集元素并入结果表 { pc->next=pa;pc=pa;pa=pa->next; } } while(pa) //删除La表剩余元素 { u=pa;pa=pa->next;free(u); } free(Lb); } }