您当前的位置:首页 > 互联网教程

单链表创建之--头插法创建带头结点的单链表,超详细

发布时间:2025-05-14 10:45:51    发布人:远客网络

单链表创建之--头插法创建带头结点的单链表,超详细

一、单链表创建之--头插法创建带头结点的单链表,超详细

单链表常见的创建方法有头插法和尾插法,这里记录头插法创建带头结点的单链表具体过程:

1)首先使用 typedef关键字定义结点数据类型

4行的 LNode和* LinkList可有可无,有的话后面定义结点变量和指针变量时更方便,不必须在LNode前面加 struct关键字,可直接这样定义变量,

与上面 typedef关键字定义的单链表数据类型一样的定义方法:

若用这种方法定义链表结点类型,定义结点变量和指针变量时必须在LNode前带上 struct关键字,即:

这两种定义方法效果是一样的,都是定义了包含 1个整型变量的数据域和 1个后继指针域的单链表结点类型

2)通过函数头插构建链表,并返回 LinkList类型表头指针变量 L,

算法基本思想:带有头结点的单链表有两类结点,头结点和元素结点,头结点通常不存储数据,用 L表示,元素结点存储数据,用 s表示

2.1定义头结点指针变量 L和元素结点 s

2.2定义了头结点之后,内存中尚未分配空间,此时头结点并不真实存在,需使用 malloc关键字分配存储空间后,并使 L指针指之,才真正创建了 L头结点。由于此时仅有头结点,无后继结点,需将其指针域置空

这时设置一个整型变量 x,通过不断输入其值,来初始化各结点数据域 val,判断 x=9999时为输入结束条件,先任意输入一个 x,然后通过 while循环来判断 x值决定是否进入添加结点过程

1,初始化一个 s元素结点,先初始化数据域 var,然后初始化指针域 next

先初始化数据域 var,然后初始化指针域 next头插法是这样插入新结点的,新的结点 s始终在当前的表中第一个元素结点之前

,也就是 L->next之前插入,数据输入顺序与最终链表结点顺序是相反的,

所以在创建了一个新的元素结点 s后,需要将其指针域置为 L->next,如图

4,若输入的值非9999,则再次进入 while循环,反复执行上述流程,不断插入元素结点扩大单链表长,这里赘述再添加一个元素结点的过程

又初始化了一个元素结点 s,状态如图:

按照上述算法,头插法新的元素结点 s插入时始终插入在当前表中首个元素结点 F之前,故需要将其后继指针域置为当前表中首个元素结点 F,即 s->next= L->next,记住 L->next始终指向首个元素结点,结果如图:

元素结点 s被“半插入”到表中后, F已经不是绝对意义上的首个元素结点了,此时需要更改头结点 L的后继指针域,将其后继指针域置为被“半插入”表中的新元素结点 s,这样,新的元素结点 s正式被插入表中,表长+1,如图

2.3上述插入过程的函数完整实现:

需要初始化一个 head指针变量,来接收 head_Insert()函数所返回的已创建的链表头结点指针值,然后将 head传入 printList()函数直接调用打印输入单链表数据,由于printList()是从首个结点开始打印,而头结点不存储数据,故传入第一个元素结点

程序最终运行结果如图,可以看到,头插法建立的单链表数据顺序与输入顺序相反:

二、下列代码用C语言求单链表的长度为什么不对

1、很高兴为楼主解答,首先楼主是想头插入法创建单链表,然后按输入的逆顺序输出,然后尾插入法创建单链表,然后按输入的顺序输出,接着输出第一个链表的长度和第二个链表的长度。但楼主犯了一个简单的错误用getchar来判断是否输入来创建链表,因为空字符也会作为字符来判断,但不是'a'字符(包括回车)也会创建一个结点,这就是为什么楼主的链表的长度是2倍的原因,楼主可以通过输入的数据来判断是否创建结点,比如说把int ch;输入的ch不为0创建一个结点,一直下去,直到输入的数据为0,替楼主的代码稍作了修改,如果可以,希望楼主采纳!!!!

2、 head=(linklist*)malloc(sizeof(linklist));

3、 p=(linklist*)malloc(sizeof(linklist));

4、 linklist*head,*p,*r;intch;//修改

5、 head=(linklist*)malloc(sizeof(linklist));

6、 p=(linklist*)malloc(sizeof(linklist));

7、 printf("%-3d",p->data);//修改

三、c语言 链表操作:建立,显示及节点的插入,删除

先写个头文件,包含链表的各种操作。具体代码如下:

typedef LNode*LinkList;//另一种定义LinkList的方法

//单链表线性表的基本操作(12个)

//操作结果:构造一个空的线性表L

L=(LinkList)malloc(sizeof(LNode));//产生头结点,并使L指向此头结点

void CreateList_L(LinkList&L, int n)//算法2.11

//逆位序输入(随机产生)n个元素的值,建立带表头结点的单链线性表L

L=(LinkList)malloc(sizeof(LNode));

L->next= NULL;//先建立一个带头结点的单链表

p=(LinkList)malloc(sizeof(LNode));//生成新结点

p->data= rand()%200;//改为一个随机生成的数字(200以内)

//初始条件:线性表L已存在。操作结果:销毁线性表L

int ClearList(LinkList L)//不改变L

//初始条件:线性表L已存在。操作结果:将L重置为空表

p=L->next;// p指向第一个结点

L->next=NULL;//头结点指针域为空

//初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE

//初始条件:线性表L已存在。操作结果:返回L中数据元素个数

LinkList p=L->next;// p指向第一个结点

int GetElem(LinkList L,int i,ElemType&e)//算法2.8

// L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回1,否则返回-1

LinkList p=L->next;// p指向第一个结点

while(p&&j<i)//顺指针向后查找,直到p指向第i个元素或p为空

if(!p||j>i)//第i个元素不存在

int LocateElem(LinkList L,ElemType e,int(*compare)(ElemType,ElemType))

//初始条件:线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)

//操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。

//若这样的数据元素不存在,则返回值为0

if(compare(p->data,e))//找到这样的数据元素

int PriorElem(LinkList L,ElemType cur_e,ElemType&pre_e)

//操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,

//返回1;否则操作失败,pre_e无定义,返回-1

LinkList q,p=L->next;// p指向第一个结点

while(p->next)// p所指结点有后继

int NextElem(LinkList L,ElemType cur_e,ElemType&next_e)

//操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,

//返回1;否则操作失败,next_e无定义,返回-1

LinkList p=L->next;// p指向第一个结点

while(p->next)// p所指结点有后继

int ListInsert(LinkList L,int i,ElemType e)//算法2.9。不改变L

//在带头结点的单链线性表L中第i个位置之前插入元素e

while(p&&j<i-1)//寻找第i-1个结点

if(!p||j>i-1)// i小于1或者大于表长

s=(LinkList)malloc(sizeof(LNode));//生成新结点

int ListDelete(LinkList L,int i,ElemType&e)//算法2.10。不改变L

//在带头结点的单链线性表L中,删除第i个元素,并由e返回其值

while(p->next&&j<i-1)//寻找第i个结点,并令p指向其前趋

if(!p->next||j>i-1)//删除位置不合理

q=p->next;//删除并释放结点

int ListTraverse(LinkList L,void(*vi)(ElemType))

// vi的形参类型为ElemType,与bo2-1.cpp中相应函数的形参类型ElemType&不同

//操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败

LinkList ReverseList(LinkList phead)//实现链表的逆置

#endif// LINKEDLIST_H_INCLUDED

int compare(ElemType c1,ElemType c2)

void MergeList_L(LinkList&La, LinkList&Lb, LinkList&Lc)

//已知单链线性表La和Lb的元素按值非递减排列。

//归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。

Lc= pc= La;//用La的头结点作为Lc的头结点

if(pa->data<= pb->data)

pc->next= pa? pa: pb;//插入剩余段

printf("在L的表尾依次插入10个数据后:L=");

printf("第4个元素的值为:%d\n",e);

ListDelete(L,4,e);//删除第4个数据

printf("删除第4个数据后:L=");