链表
来源:互联网 发布:python return 空 编辑:程序博客网 时间:2024/06/03 14:25
也许迷途的惆怅
会折碎我的脚步
可我相信未来
会给我一双梦想的翅膀
虽然失败的苦痛
已让我遍体鳞伤
可我坚信光明就在远方
我用翅膀掀起那天边的排浪
我用身躯托起那血红的太阳
就在这刺骨而凛冽的大风中
你会听到我赞美未来的呼喊
也许征程的迷惘
会折碎我的手臂
可我相信未来
会给我一双梦想的翅膀
虽然挫折的创伤
已让我寸步难行
可我坚信光明就在远方
可我坚信光明就在远方
—原唱汪峰《光明》(可我喜欢的是罗京民版——沧桑、和数十年对人生的感悟)
关于Status InitList(LinkList *L)的问题详情参见 C语言函数传递指针参数的问题
函数中改变变量的内容就要找到它的地址
现在的问题是LinkList L;这条语句怎么实现的(给L开辟了一个怎样的空间,空间大小,空间里的值是什么);
当运行DestoryList(&L)后L又变成了什么?
单链表
头文件、宏定义、存储结构
/* c1.h (程序名) */ #include<string.h> #include<ctype.h> #include<malloc.h> /* malloc()等 */ #include<limits.h> /* INT_MAX等 */ #include<stdio.h> /* EOF(=^Z或F6),NULL */ #include<stdlib.h> /* atoi() */ #include<io.h> /* eof() */ #include<math.h> /* floor(),ceil(),abs() */ #include<process.h> /* exit() */ #include<conio.h> /* 函数结果状态代码 */ #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */ typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef int ElemType;//将整型作为数据元素//单链表struct LNode { ElemType data; struct LNode *next; }; typedef struct LNode *LinkList; typedef struct LNode LNode;
改变L内容的InitList、DestoryList
Status InitList(LinkList *L)//改变L的内容 { // 操作结果:构造一个空的线性表L *L=(LinkList)malloc(sizeof(struct LNode)); //产生头结点,并使L指向此头结点 if(!*L) //存储分配失败 exit(OVERFLOW); (*L)->next=NULL; //指针域为空 return OK; } Status DestroyList(LinkList *L)//改变L的内容 { //释放包括头节点的所有节点 LinkList q; while(*L) { q=(*L)->next; //先保存下一个节点的地址,把当前节点释放(不然找不到下一个节点) free(*L); *L=q; } return OK; }
ClearList、ListEmpty、ListLength
Status ClearList(LinkList L) { //释放除头节点外的节点 LinkList p,q; p=L->next; while(p) //因为是释放当前节点,所以判断当前节点是否为空 { q=q->next; free(p); p=q; } L->next=NULL; return OK; } Status ListEmpty(LinkList L) {//判断L是否为空表(只有头节点)空表返回TRUE,否则返回FALSE if(L->next) return TRUE; else return FALSE; } int ListLength(LinkList L) { //返回数据元素个数 int i=0; LinkList p; p=L->next; while(p) {//当前节点不为空计数器加一 i++; p=p->next; } return i; }
GetElem、LocateElem、PriorElem、NextElem
Status GetElem(LinkList L,int i,ElemType *e)//这里的ElemType指的是链表单元的数据类型 { //查找第i个位置的数据元素,弱存在其值付赋给e,返回OK LinkList p; p=L->next;//从首元结点开始 int j=1;//计数器开始为 1 while(p&&j<i)//顺着指针查找,未找到前当前节点为空自然退出 { //这里说一下为啥(j<i) //如果改成j<=i;当循环到j=i时,跳出循环后p指向的是i+1节点 p=p->next; j++; } //跳出循环后p指向的就是第i个节点 if(!p||j<i)//第i个元素 return ERROR; *e=p->data; return OK; }Status equal(ElemType c1,ElemType c2){ if(c1==c2) return TRUE; return FALSE;} int LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType)) { //通过比较确定数据元素位置 ,找到返回数据元素位置,不然返回0 int i=0; LinkList p=L->next;//从首元节点开始比较 while(p) { //当前节点不为空计数器加一 i++; if(compare(p->data,e)) return i; } return 0; }Status PriorELem(LinkList L,ElemType cur_e,ElemType *pre_e){ LinkList p,q; p=L->next; //首元结点必然不能是目标节点 //首元结点必然要有直接后继,这是while初始条件 while(p->next) { q=p->next;//p保留当前节点q的直接前驱, if(q->data==cur_e) { *pre_e=q->data; return OK; } p=q; } return INFEASIBLE;}Status NextElem(LinkList L,ElemType cur_e,ElemType *next_e){ //返回目标节点的直接后继,不用额外变量保留上一节点信息 LinkList p=L->next; while(p->next) { if(p->data==cur_e) { *next_e=p->next->data; return OK; } p=p->next; } return INFEASIBLE;}
ListInsert、ListDelete、ListTraverse
Status ListInsert(LinkList L,int i,ElemType e){ LinkList p,s; p=L;// int j=0; if(i<1||i>ListLength(L)+1) //插入位置不合理 return ERROR; while(p&&j<i-1) {//插入位置是i-1后面 //循环条件是当前节点不为空且指针位置未到i-1 p=p->next; j++; } //跳出循环p指向i-1节点 s=(LinkList)malloc(sizeof(struct LNode)); if(!s) exit(OVERFLOW); s->data=e; //注意指针改变的顺序 s->next=p->next; p->next=s; return OK;}Status ListDelete(LinkList L,int i,ElemType *e){//找到第i-1节点的位置,释放第i个节点 LinkList p=L; int j=0; if(i<0||i>ListLength(L))//不能删除第0个节点以及第n+1个节点 return ERROR; while(p->next&&j<i-1) { j++; p=p->next; } LinkList q=p->next; p->next=q->next; *e=q->data; free(q); return OK;} void Printf(ElemType e) { printf("%d ",e); }Status ListTraverse(LinkList L,void (* vi)(ElemType)){ LinkList p=L->next; while(p) { vi(p->data); p=p->next; } printf("\n"); return OK;}
循环双链表
typedef int ElemType;//将整型作为数据元素struct LNode { ElemType data; struct LNode *next; struct LNode *prior; }; typedef struct LNode *DuLinkList; typedef struct LNode DuLNode; Status InitList(DuLinkList *L) {//头指针尾指针都指向自己 *L=(DuLinkList)malloc(sizeof(struct LNode)); if(!*L) exit(OVERFLOW); //空表的象征是next、prior都指向L (*L)->next=*L; (*L)->prior=*L ; return OK; } Status DestoryList(DuLinkList *L) {//释放所有内存 DuLinkList p,q; p=(*L)->next; while(p!=*L)//由于是循环链表尾节点的next指向头节点 { q=p->next; free(p); p=q; } free(*L); *L=NULL; return OK; } Status ClearList(DuLinkList L) { //空表的象征是next、prior都指向L DuLinkList p,q; p=L->next; while(p!=L) { q=p->next; free(p); p=q; } L->next=L; L->prior=L; } Status ListEmpty(DuLinkList L) {//空表的象征是next、prior都指向L if(L->next==L&&L->prior==L) return TRUE; return FALSE; } int ListLength(DuLinkList L) { int i=0; DuLinkList p; p=L->next; while(p!=L) { i++; p=p->next; } return i; } Status GetElem(DuLinkList L,int i,ElemType *e) { int j=1;//表示节点序号从1开始 if(i<1||i>ListLength(L)) return ERROR; DuLinkList p; p=L->next; while(p!=L&&j<i) { //循环结束指针指向第i个元素 j++; p=p->next; } *e=p->data; return OK; } int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType)) { int i=0; DuLinkList p; p=L->next; while(p!=L) { i++; if(compare(p->data,e)) return i; p=p->next; } return 0; } Status PriorElem(DuLinkList L,ElemType cur_e,ElemType *pre_e) { DuLinkList p,q; p=L->next->next; while(p!=L)//未到表头 { if(p->data==cur_e) { *pre_e=p->prior->data; return TRUE; } p=p->next; } return FALSE; } Status NextElem(DuLinkList L,ElemType cur_e,ElemType *next_e) { DuLinkList p,q; p=L->next; while(p->next!=L)//p的下一个节点不是表头 { if(p->data==cur_e) { *next_e=p->next->data; return TRUE; } p=p->next; } return FALSE; } Status ListInsert(DuLinkList L,int i,ElemType e) { int j=1; if(i<1||i>ListLength(L)+1) return ERROR; DuLinkList p,q,s; p=L->next; while(p!=L&&j<i) p=p->next; s=(DuLinkList)malloc(sizeof(DuLNode)); if(!s) return OVERFLOW; s->data=e; q=p->prior; q->next=s; s->prior=q; s->next=p; p->prior=s; return OK; } Status ListDelete(DuLinkList L,int i,ElemType *e) { DuLinkList p,q; if(i<1||i>ListLength(L)) return ERROR; p=L->next; int j=1; while(p!=L&&j<i) { j++; p=p->next; } *e=p->data; q=p->prior; q->next=p->next; p->next->prior=q; free(p); return OK; } void Printf(ElemType e) { printf("%d ",e); } void ListTraverse(DuLinkList L,void(*visit)(ElemType)) { // 由双链循环线性表L的头结点出发,正序对每个数据元素调用函数visit() DuLinkList p=L->next; /* p指向头结点 */ while(p!=L) { visit(p->data); p=p->next; } printf("\n"); } void ListTraverseBack(DuLinkList L,void(*visit)(ElemType)) { // 由双链循环线性表L的头结点出发,逆序对每个数据元素调用函数visit()。 DuLinkList p=L->prior; /* p指向尾结点 */ while(p!=L) { visit(p->data); p=p->prior; } printf("\n"); }
阅读全文
0 0