数据结构学习笔记 --- 线性表 (单链表)
来源:互联网 发布:淘宝售后规则 编辑:程序博客网 时间:2024/05/18 13:47
1. 引言
尾插法创建单链表,以及两个算法。单链表有带有结点和不带头结点之分,本文分别讨论带头结点的单链表和不带头结点的单链表的一些基本操作,和用头插法、
2. 带头结点的单链表
2.1 带头结点的单链表的存储结构
typedef struct LNode{ElemType data;struct LNode *next;}LNode, *LinkList;
2.2 带头结点的单链表的基本操作
本文不做一一介绍,只介绍几个比较重要的基本操作。
(1)返回L中第1个与e满足关系compare()的数据元素的位序
// 初始条件: 线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)// 操作结果: 返回L中第1个与e满足关系compare()的数据元素的位序。// 若这样的数据元素不存在,则返回值为0int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType)){LinkList p = L->next;inti = 0;while(p) { i++; if(compare(p->data,e)) // 找到这样的数据元素 return i; p=p->next; } return 0;}
(2)前驱和后继
// 初始条件: 线性表L已存在// 操作结果: 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,// 返回OK;否则操作失败,pre_e无定义,返回INFEASIBLEStatus PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e){LinkList q,p=L->next; // p指向第一个结点 while(p->next) // p所指结点有后继 { q=p->next; // q为p的后继 if(q->data==cur_e) { pre_e=p->data; return OK; } p=q; // p向后移 } return INFEASIBLE;}// 初始条件:线性表L已存在// 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,// 返回OK;否则操作失败,next_e无定义,返回INFEASIBLEStatus NextElem(LinkList L, ElemType cur_e, ElemType &next_e){LinkList p = L->next; // p指向第一个结点while (p->next) // p所指结点有后继{if ( p->data == cur_e){next_e = p->next->data;return OK;}p = p->next;}return INFEASIBLE;}
(3)插入和删除
// 在带头结点的单链线性表L中第i个位置之前插入元素eStatus InsertList(LinkList L, int i, ElemType e){intj = 0;LinkListp = L, pnew;// 寻找第i-1个结点while (j < i-1 && p){p = p->next;j++;}if (!p || j > i-1) // i小于1或者大于表长return ERROR;pnew = (LinkList)malloc(sizeof(LNode));if (!pnew)exit(OVERFLOW);pnew->data = e;pnew->next = p->next;p->next = pnew;return OK;}// 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值Status DeleteList(LinkList L, int i, ElemType &e){intj = 0;LinkListp = L, q;// 寻找第i个结点,并令p指向其前驱while (j < i-1 && p->next){p = p->next;j++;}if (!(p->next) && j>i-1 ) // 删除位置不合理return ERROR;q = p->next;e = q->data;p->next = q->next;free(q);return OK;}
(4)头插法和尾插法创建单链表
// 逆位序(插在表头)输入n个元素的值,建立带表头结构的单链线性表Lvoid HeadCreList(LinkList &L, int n){LinkList head;L = (LinkList)malloc(sizeof(LNode));if (!L) exit(OVERFLOW);L->next = NULL;printf("please input %d element.\n", n);for (int i = 0; i < n; i++){head = (LinkList)malloc(sizeof(LNode));if (!head) exit(OVERFLOW);scanf("%d", &(head->data));head->next = L->next; // 插入到表头L->next = head;}}// 正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表Lvoid TailCreList(LinkList &L, int n){LinkList temp, tail;L = (LinkList)malloc(sizeof(LNode));if (!L) exit(OVERFLOW);L->next = NULL;tail = L; // 总是让tail指向链表的尾结点printf("please input %d element.\n", n);for (int i = 0; i < n; i++){temp = (LinkList)malloc(sizeof(LNode));if (!temp) exit(OVERFLOW);scanf("%d", &(temp->data));tail->next = temp;tail = tail->next; // 总是让tail指向链表的尾结点}tail->next = NULL;// 不要忘记将尾结点的next指针置为空}
(5)两个算法
// 将所有在线性表Lb中但不在La中的数据元素插入到La中void Union(LinkList &La, LinkList Lb){int la_len = ListLength(La);LinkList pa = La->next, pb = Lb->next;while (pb){if (!LocateElem(La, pb->data, compare))InsertList(La,++la_len, pb->data);pb = pb->next;}}// 已知单链线性表La和Lb的元素按值非递减排列。// 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列void MergeList(LinkList La, LinkList Lb, LinkList &Lc){LinkList pa = La->next, pb = Lb->next, pc;Lc = pc = La;//同时遍历链表La和Lbwhile (pa && pb){if (pa->data > pb->data){pc->next = pb;pb = pb->next;}else{pc->next = pa;pa = pa->next;}pc = pc->next;}pc->next = pa ? pa : pb;// 插入剩余段 free(Lb); // 释放Lb的头结点 Lb=NULL;}
3. 不带头结点的单链表
3.1 不带头结点的单链表的存储结构(和带头结点的一样)
typedef struct LNode{ElemType data;struct LNode *next;}LNode, *LinkList;
3.2 不带头结点的单链表的基本操作
(1)插入和删除
// 在带头结点的单链线性表L中第i个位置之前插入元素eStatus InsertList(LinkList &L, int i, ElemType e){intj = 1;LinkListp = L, pnew;if(i<1) // i值不合法 return ERROR; pnew = (LinkList)malloc(sizeof(LNode));if (!pnew)exit(OVERFLOW);pnew->data = e; if (1 == i){pnew->next = L;L = pnew; // 改变L}else{// 寻找第i-1个结点while (j < i-1 && p){p = p->next;j++;}if (!p) // i大于表长return ERROR;pnew->next = p->next;p->next = pnew;}return OK;}// 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值Status DeleteList(LinkList &L, int i, ElemType &e){intj = 1;LinkListp = L, q; if (1 == i){L = p->next;// L由第2个结点开始e = p->data;free(p);}else{// 寻找第i个结点,并令p指向其前驱while (j < i-1 && p->next){p = p->next;j++;}if(!p->next || j>i-1) // 删除位置不合理return ERROR;q = p->next;e = q->data;p->next = q->next;free(q);}return OK;}
(2)头插法和尾插法创建单链表
// 逆位序(插在表头)输入n个元素的值,建立带表头结构的单链线性表Lvoid HeadCreList(LinkList &L, int n){LinkList head;L = NULL;printf("please input %d element.\n", n);for (int i = 0; i < n; i++){head = (LinkList)malloc(sizeof(LNode));if (!head) exit(OVERFLOW);scanf("%d", &(head->data));head->next = L; // 插入到表头L = head;}}// 正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表Lvoid TailCreList(LinkList &L, int n){LinkList temp, tail;printf("please input %d element.\n", n);for (int i = 0; i < n; i++){temp = (LinkList)malloc(sizeof(LNode));if (!temp) exit(OVERFLOW);scanf("%d", &(temp->data));if (0 == i){L = tail = temp;}else{tail->next = temp;tail = tail->next; // 总是让tail指向链表的尾结点}}tail->next = NULL;// 不要忘记将尾结点的next指针置为空}(3)两个算法
// 将所有在线性表Lb中但不在La中的数据元素插入到La中void Union(LinkList &La, LinkList Lb){int la_len = ListLength(La);LinkList pa = La, pb = Lb;while (pb){if (!LocateElem(La, pb->data, compare))InsertList(La,++la_len, pb->data);pb = pb->next;}}// 已知单链线性表La和Lb的元素按值非递减排列。// 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列void MergeList(LinkList La, LinkList Lb, LinkList &Lc){LinkList pa = La, pb = Lb, pc;int isfirst = 1;//同时遍历链表La和Lbwhile (pa && pb){if (isfirst){if (pa->data > pb->data){Lc = pc= pb;pb = pb->next;}else{Lc = pc = pa;pa = pa->next;}isfirst = 0;}else{if (pa->data > pb->data){pc->next = pb;pc = pb;pb = pb->next;}else{pc->next = pa;pc = pa;pa = pa->next;}}}pc->next = pa ? pa : pb;// 插入剩余段}
- 数据结构学习笔记 --- 线性表 (单链表)
- 数据结构学习笔记 --- 线性表 (单链表)
- 数据结构学习笔记(2)线性表
- 数据结构学习笔记1-线性表(顺序表,单链表)
- 数据结构学习笔记(一)---------线性表线性存储
- 数据结构-线性表(学习笔记)
- 数据结构学习笔记-线性表
- 数据结构学习笔记(2.线性表之单链表)
- 数据结构学习笔记(2.线性表之单链表)
- 数据结构学习笔记 --- 线性表 (顺序表)
- 数据结构学习笔记 --- 线性表 (顺序表)
- 数据结构学习笔记(3)线性表-顺序映像
- 数据结构学习笔记(4)线性表-链式映像
- 数据结构学习笔记 --- 线性表 (应用举例)
- 数据结构与算法学习笔记02_1(线性表)
- 数据结构与算法学习笔记02_2(线性表)
- 数据结构与算法学习笔记02_3(线性表)
- 【数据结构】学习笔记(一)——线性表
- sql convert 函数
- 强大的Web画图JavaScript库 – mxgraph
- NYOJ--第79题拦截导弹
- 总也记不住的update语法>_< sql update set
- Java动态代理剖析(一)
- 数据结构学习笔记 --- 线性表 (单链表)
- 文本 溢出 自动缩短 样式
- BOM的问题
- android:m/mm/mmm
- 跑业务的学学吧
- Android菜鸟历程3
- 图论解题报告导引
- Hibernate+spring数据延迟加载问题解决方案。
- 为什么javascript加载xml文件,在Chrome下不成功!