实际应用中带头节点的线性链表
/*========带头节点的线性链表类型=========*/
typedef char ElemType//结点类型
typedef struct LNode
{char data;struct LNode *next;
}*Link,*Position;//链表类型
typedef struct
{Link head,tail;int len;
}LinkList;/*======================================================*/
/*=======一些在其他函数定义中会调用的函数===============*/
/*======================================================*//*---compare---比较两个元素的大小关系*/
int Compare(char a,char b)
{ return a-b;
}/*---visit---*/
int Visit(Link p)
{if(...)return 1;elsereturn 0;}/*---length---求链的长度*/
int Length(Link s)
{ int i=0;Link p=NULL;p=s;while(p->next!=NULL){p=p->next;i++;}return i;
}/*---print---在屏幕上输出链表的所有元素*/
void Print(LinkList L)
{ Link p=NULL;p=L.head;if(!p->next){printf("\nThe LinkList is empty.\n\n");return ;}printf("The List:");while(p){printf("%c-",p->data);p=p->next;}
}/*======================================================*/
/*==========对带头结点的单链线性表进行操作的函数的定义==*/
/*======================================================*//*---分配由p指向的结点并赋值为e---*/
Position MakeNode(ElemType e)
{ Link p=NULL;p=(Link)malloc(sizeof(struct LNode));if(p){p->data=e;p->next=NULL;}else return;return p;
}/*---释放p所指向的结点-*/
void FreeNode(Link p)
{ free(p);
}/*---构造一个由L指向的空的线性表-*/
void InitList(LinkList *L)
{ L->head=MakeNode('L');//生成头结点L->head->next=NULL;/*不是l->head=NULL*/L->tail=L->head;L->len=0;
}/*----------销毁由L指向的线性表---------*/
void DestroyList(LinkList *L)
{ Link p;p=(*L).tail;while(p!=(*L).head){p=PriorPos(*L,p);FreeNode(p->next);}FreeNode((*L).head);
}/*将线性表L置为空表,并释放原链表的头结点*/
void ClearList(LinkList *L)
{ Link p;p=(*L).tail;while(p!=(*L).head){p=PriorPos(*L,p);FreeNode(p->next);}FreeNode((*L).head);
}/*---将s指向的结点插入线性链表的第一个结点之前-*/
void InsFirst(LinkList *L,Link s)
{ s->next=L->head->next;if(!L->head->next) L->tail=s; /*当向一个空的线性表执行该操作时*/L->head->next=s;L->len++;
}/*---删除表中第一个结点并以q返回-*/
void DelFirst(LinkList *L,Link q)
{ if(!L->head->next){printf("\nThe LinkList is empty,can not delete..\n");return 0;}q=L->head->next;L->head->next=L->head->next->next;
}/*---将指针s所的一串结点链接在线性表L的最后一个结点-*/
void Append(LinkList *L,Link s)
{ Link q;q=L->head;if(!L->tail){/*考虑到链表为空的情况*/L->head->next=s;while(q->next) q=q->next;/*尾结点的处理*/L->tail=q;}L->tail->next=q=s;while(q->next) q=q->next;/*不能忘了对尾结点的处理*/L->tail=q;L->len+=Length(s);
}/*---删除线性表l中的尾结点-*/
void Remove(LinkList *L,Link q)
{ if(!L->tail){printf("\nthe LinkList is empty,can not remonde..\n");return 0;}q=L->tail; L->tail=PriorPos(*L,q);L->tail->next=NULL;
}/*---将s所指向结点插入在p所指结点之前-*/
void InsBefore(LinkList *L,Link p,Link s)
{ Link q;q=PriorPos(*L,p);s->next=p;q->next=s;
}/*---将s所指向结点插入在p所指结点之后-*/
void InsAfter(LinkList *L,Link p,Link s)
{ s->next=p->next;p->next=s;
}/*---用e更新p所指向的当前结点-*/
void SetCurElem(Link p,ElemType e)
{ p->data=e;
}/*---返回p所指结点中元素的值-*/
ElemType GetCurElem(Link p)
{ return p->data;
}int Listempty(LinkList L)
{ /*---若线性表为空表则返回1,否则返回0-*/if(L.head==L.tail) return 1;return 0;
}int Listlength(LinkList L)
{ /*---返回线性表中元素个数-*/return L.len;
}Position GetHead(LinkList L)
{ /*---返回线性表l中头结点的位置-*/return L.head;
}Position GetLast(LinkList L)
{ /*-----返回线性表l中最后一个结点的位置-------*/return L.tail;
}/*---返回p所指结点的直接前驱的位置-*/
Position PriorPos(LinkList L,Link p)
{ Link q;q=L.head;if(q->next==p) return 0;while(q->next!=p) q=q->next;return q;
}/*-----返回p所指结点的直接后继的位置-------*/
Position NextPos(Link p)
{ Link q;q=p->next;return q;
}/*-----用p返回线性表l中第i个结点的位置,并返回ok-------*/
void LocatePos(LinkList L,int i,Link p)
{ p=L.head;if(i<=0||i>Listlength(L)) return 0;while(i){p=p->next;i--;}
}/*----返回表中第一个与e满足一定函数关系的结点次序位置----*/
int LocatElem(LinkList L,ElemType e)
{ int i=0;Link p;p=L.head->next;while(compare(p->data,e)&&p){p=p->next;++i;}if(!p){/*考虑到查找不到指定元素的情况*/printf("\nthere's no '%c' in this LinkList.",e);return 0;}return i;
}/*----用一个函数遍历表中所有结点-------*/
void ListTraverse(LinkList L)
{ Link p;p=L.head;while(!visit(p)) p=p->next;
}
将单链线性表La和Lb的元素按值非递减排列
Status MergeList_L(NLinkList &La, NLinkList &Lb, NLinkList &Lc, int (*compare)(ElemType, ElemType))
{ // 算法2.21// 已知单链线性表La和Lb的元素按值非递减排列。// 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。NLink ha, hb;Position pa, pb, q;ElemType a, b;if (!InitList(Lc)) return ERROR; // 存储空间分配失败ha = GetHead(La); // ha和hb分别指向La和Lb的头结点hb = GetHead(Lb);pa = NextPos(La, ha); // pa和pb分别指向La和Lb中当前结点pb = NextPos(Lb, hb);while (pa && pb) { // La和Lb均非空a = GetCurElem(pa); // a和b为两表中当前比较元素b = GetCurElem(pb);if ((*compare)(a, b)<=0) { // a≤bDelFirst(ha, q); Append(Lc, q); pa = NextPos(La, pa); } else{ // a>bDelFirst(hb, q); Append(Lc, q); pb = NextPos(Lb, pb); }} // whileif (pa) Append(Lc, pa); // 链接La中剩余结点elseAppend(Lc, pb); // 链接Lb中剩余结点FreeNode(ha); FreeNode(hb); // 释放La和Lb的头结点return OK;
} // MergeList_L
实际应用中带头节点的线性链表相关推荐
- 【数据结构】8. 队列(带头节点的单链表实现)(完整代码实现:初始化、入队列、出队列、获取队头元素、获取队尾元素、获取队列中有效元素的个数、判空、销毁)
目录 Queue.h Queue.c test.c Queue.h #pragma once //采用带头节点的单链表实现队列typedef int DataType;typedef struct Q ...
- 建立一个带头结点的线性链表,用以存放输入的二进制数,链表的每一个节点的data域存放一个二进制位。并在此链表上实现对二进制数加1的运算;
1.题目:建立一个带头结点的线性链表,用以存放输入的二进制数,链表的每一个节点的data域存放一个二进制位.并在此链表上实现对二进制数加1的运算: 部分函数调用参考:https://blog.csdn ...
- 带头结点的线性链表的基本操作
持续了好久,终于有了这篇博客,链表的操作需要借助图像模型进行反复学习,这里尽可能的整理并记录下自己的思考,以备后面复习,和大家分享.需要说明的是,我们从实际应用角度出发重新定义了线性表. 一. 定义 ...
- 不带头节点的单链表如何头插(多图易懂)
文章目录 缘起 带头节点的头插 不带头节点的头插 错误的代码 为什么错误 如何修改 返回新的头指针 二级指针 缘起 本文想说的是单向非循环链表的头插.单向非循环链表,可以是带头节点的,也可以是不带头节 ...
- 【不带头节点的单链表】
不带头节点的单链表 前言 一.结构体设计 二.函数实现 1. 初始化 2. 购买一个新节点 3. 头插 4. 尾插 5. 按位置插入 6. 头删 7. 尾删 8. 按位置删 总结 补充代码 前言 单链 ...
- 数据结构-带头节点的单链表(C语言)超详细讲解
前面我们学到线性表的顺序存储结构(顺序表),发现它有着明显的缺点:插入和删除元素时需要频繁的移动元素,运算效率低.必须按事先估计的最大元素个数申请连续的存储空间.存储空间估计大了,造成浪费空间:估计小 ...
- 无头结点单链表的逆置_从无头单链表中删除节点及单链表的逆置
题目: 假设有一个没有头指针的单链表.一个指针指向此单链表中间的一个节点(非第一个节点, 也非最后一个节点).请将该节点从单链表中删除. 解答: 典型的"狸猫换太子", 若要删除该 ...
- java带头节点的单链表_自己实现集合框架(五):带头结点单链表的实现
这是系列文章,每篇文章末尾均附有源代码地址.目的是通过模拟集合框架的简单实现,从而对常用的数据结构和java集合有个大概的了解.当然实现没有java集合的实现那么复杂,功能也没有那么强大,但是可以通过 ...
- 237删除链表中的节点(单链表基本操作)
1.题目描述 请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点. 说明: 链表至少包含两个节点. 链表中所有节点的值都是唯一的. 给定的节点为非末尾节点并且一定 ...
最新文章
- TensorFlow王位不保?ICLR投稿论文PyTorch出镜率快要反超了
- 张亚勤2020寄语哥伦比亚大学毕业生:引领未知时代
- python语言命令大全-Python常用命令之集合
- Linux压缩包和用户管理及开关机指令
- b区计算机复试国家线,2020研究生考试国家线A区B区有什么区别
- 【原生】封装一个判断数据类型的函数的方法,准确判断一个数据的类型
- 帮你轻松理解Commonjs、AMD、CMD、ES6的区别
- JAR文件概述(2021版)
- sql语句修改mysql数据库密码_修改mysql数据库密码的3中方法
- 2.1 电子计算机的兴起
- 每日十道面试题(五)
- 【C4D周练作业061-070】用C4D做了个锤子~
- 这种国家的外贸不做也罢
- TCPIP卷一(2):二层封装之–PPP与FR
- vi编辑器中的常用命令
- 限电阴霾下的东北小商户
- mysql 实现yyyyww,在java中有YYYYWW格式吗
- 在Swagger中请求API返回400BadRequest
- 图片识别商品接口 API:天猫淘宝
- 粒子说区块链7:产业链分析之硬件篇
热门文章
- Java 线程池相关问题
- H.264软件解码器在PXA270平台上的优化
- 电脑如何获得管理员权限
- $(“#addLowForm“).serialize()同时提交其它参数的写法
- NOIP 2011 Day2
- 初学Spring Boot
- mysql在空闲8小时之后会断开连接(默认情况)
- [读书笔记]TCP/IP详解V1读书笔记-3
- C#.NET中的事件2
- 【BZOJ 3339 / BZOJ 3585 / luogu 4137】Rmq Problem / mex