线性表-----单链表
来源:互联网 发布:送货单打印软件 编辑:程序博客网 时间:2024/06/05 02:03
本来简单的代码,调试用来好长时间;
先定义了结构体
//线性表的链式表现及实现 //节点由数据域和指针域组成 typedef struct LNode{ElemType data; struct LNode *next; //指向结构体的指针}LinkList;
下来写了个单链表初始化的函数,结果出现了 隐形的错误
void Init_List(LinkList* L) ///^{L = (LinkList*) malloc (sizeof(LinkList)); //产生一个头结点,并使 L 指向这个头结点 if(!L)exit(-1);L->next = NULL; // 指针域为空 L->data = 0; }
为了检验这个函数的正确性,我写了个简单的mian函数,
int main() { LinkList L1; Init_List(&L1); printf("%d\n",L1.next); return 0; }
运行结果竟然为27,这显然是编译器的随机产生的数字。其实这个错误到了最后写遍历函数才发现的,最后确定问题出在初始化函数上,显然L->next = NULL; 这条语句并没有起到作用,是什么原因呢??最终想到两个方案。
(1)用return 改写函数的到如下:
LinkList* Init1_List(){LinkList* L = (LinkList*)malloc(sizeof(LinkList));if(!L)exit(-1);L->next = NULL;L->data = 0;return L;}
这样,经过返回值,就把L->next的值赋值为NULL,同时也把头指针的的数据域赋值为0,在这里,我想用这个的头指针数据域来存储单链表的长度,于是赋值为0;
(2)不用malloc函数给L->next分配空间。
void Init_List(LinkList* L) ///^{//L = (LinkList*) malloc (sizeof(LinkList)); //产生一个头结点,并使 L 指向这个头结点 //if(!L)//exit(-1);L->next = NULL; // 指针域为空 L->data = 0; }
如上,这样也是行的,从这个改写的结果来看,其实已经知道,在main函数中定义一个结构体变量,就已经给这个L1分配空间了,所就没有必要再分配,但是中间也有些疑惑,为什么,我传的是地址,即使分配了空间,用malloc再重新给L1赋值,应该也可以呀,为什么就不行呢???这个问题现在还没有解决。希望自己学习的深入,慢慢体会吧,同时也希望懂得人知道的话,帮我指点一二,。
接下来就是几个简单的函数,分别贴出来吧:
先是两个容易弄糊涂的函数
(1)销毁线性表
void Destroy_List(LinkList* L){LinkList* q;while(!L){q = L->next;free(L);L = q;}}
(2)清空线性表
int Clear_List(LinkList *L){LinkList *p,*q;p = L->next;while(p){q = p;free(p);p = q;}L->next = NULL;}说明:销毁单链表,包括头结点全部销毁。清空一个单链表,只把头结点以后的链表销毁,最后把头结点指针域赋值为NULL。
(3)获取给定位置的元素
1.声明一个节点 p 指向链表的第一个节点,初始化 j 从1开始
2.当 j < pos 时,遍历链表,让 p 的指针向后移动,不断指向下一个节点,同时 j 累加1
3.若链表末尾 p 为空,则说明第 pos 个元素不存在
4. 否则,查找成功,返回节点 p 的数据。
int Get_List(LinkList *L,int pos ,ElemType *e){LinkList *p;p = L->next;int j = 1;while( p && j < pos){p = p->next;++j;}if( !p || j > pos)return -1;else*e = p->data;return 1;}
(3)给定位置插入一个元素
前几步和获取一个元素是一样的,只是找到这个位置后需要创建一个空间
1. 若查找成功,在系统内生成一个空的节点 s 。
2.将元素 e 赋值给 s->data ;
3. 单链表的插入语句 s->next = p->next; p->next = s;
4.返回成功
int List_Insert(LinkList *L,int pos, ElemType e){LinkList *p ,*s;//p = L->next;p = L; //这点和 Get_List()是有区别的 int j =1;while( p && j<pos) //如果 j=0; 这里的条件就变成 j < pos -1; {p = p->next;++j;}if( !p || pos > j) //合法性判断 return -1;elses = (LinkList*)malloc(sizeof(LinkList));s->data = e;s->next = p->next;p->next = s;++(L->data);return 1;}
(4)给定位置删除元素
int List_Delete(LinkList *L,int pos, ElemType *e){int j = 0;LinkList *p,*q;p = L;while( p->next && j<pos-1){p = p->next;++j;}if( !p->next || j >pos-1)return 0;q = p->next; //删除并释放的节点 p->next = q->next;//p 现在只想下下个元素的地址 *e = q->data;free(q);return 1;}
(5)最后一个就是写的一个遍历输出的函数(两种方法实现)
void List_Traver(LinkList *L){LinkList* p = L->next;int i = 0;/*for(i ; i<L->data;++i){printf("%d\n",p->data);p = p->next;}*/while(p){printf("%d\n",p->data);p = p->next;}}
(6)下来就到main函数了
int main(int argc, char *argv[]) {LinkList *L1 = Init1_List();int e=0;List_Insert(L1,1,1);List_Insert(L1,2,2);List_Insert(L1,2,3);List_Traver(L1);Get_List(L1,2,&e);printf("获得第二个元素%d\n",e);List_Delete(L1,2,&e);printf("删除第二个元素为:%d\n",e);List_Traver(L1);Destroy_List(L1);return 0;}
总结:线性表还是比较简单的,但是有一些问题还得自己慢慢去摸索,比如结构体成员指针的初始化等等问题。
0 0
- 线性表之单链表
- (线性表)单链表
- 线性表的单链表
- 线性表之单链表
- 线性表->单链表
- 线性表--单链表(尾插法)
- 线性表之单链表
- 线性表-----单链表
- 线性表之单链表
- 数据结构-线性表--单链表
- 线性表之单链表
- 线性表的单链表
- 线性表之单链表
- 线性表--单链表
- 【线性表】单链表
- 线性表之单链表
- 线性表--单链表(C++)
- 线性表2--单链表
- javascrip 的 date
- 详解 QT 框架中快速应用OpenCV 基于图片,基于视频
- 深入理解JavaScript系列(32):设计模式之观察者模式
- class struct
- 深入理解JavaScript系列(34):设计模式之命令模式
- 线性表-----单链表
- 深入理解JavaScript系列(35):设计模式之迭代器模式
- **Leetcode_median-of-two-sorted-arrays (c++ and python version)
- JavaScript实现的购物车效果-好友列表效果
- 详细了解SQLITE 优缺点 性能测试
- 深入理解JavaScript系列(36):设计模式之中介者模式
- Android画图Path的使用
- 【中断异常】X86对中断的支持原理
- Eclipse开发工具知识必备