C语言的单链表问题,谢谢解答

Python012

C语言的单链表问题,谢谢解答,第1张

单链表简介

链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

单链表

以"结点的序列"表示线性表称作线性链表(单链表)

单链表是链式存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。

因此,查找第 i 个数据元素的基本操作为:移动指针,比较 j 和 i

单链表

1、链接存储方法

链接方式存储的线性表简称为链表(Linked List)。

链表的具体存储表示为:

① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)

② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))

注意:

链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。

2、链表的结点结构

┌───┬───┐

│data │next │

└───┴───┘

data域--存放结点值的数据域

next域--存放结点的直接后继的地址(位置)的指针域(链域)

注意:

①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。

②每个结点只有一个链域的链表称为单链表(Single Linked List)。

【例】线性表(bat,cat,eat,fat,hat,jat,lat,mat)的单链表示如示意图

3、头指针head和终端结点指针域的表示

单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。

注意:

链表由头指针唯一确定,单链表可以用头指针的名字来命名。

终端结点无后继,故终端结点的指针域为空,即NULL。

4、单链表的一般图示法

由于我们常常只注重结点间的逻辑顺序,不关心每个结点的实际位置,可以用箭头来表示链域中的指针,线性表(bat,cat,fat,hat,jat,lat,mat)的单链表就可以表示为下图形式。

5、单链表类型描述

typedef char DataType//假设结点的数据域类型为字符

typedef struct node{ //结点类型定义

DataType data//结点的数据域

struct node *next//结点的指针域

}ListNode

typedef ListNode *LinkList

ListNode *p

LinkList head

注意:

①LinkList和ListNode是不同名字的同一个指针类型(命名的不同是为了概念上更明确)

②*LinkList类型的指针变量head表示它是单链表的头指针

③ListNode类型的指针变量p表示它是指向某一结点的指针

6、指针变量和结点变量

指针变量

结点变量

定义

在变量说明部分显式定义

在程序执行时,通过标准函数malloc生成

取值

非空时,存放某类型结点

实际存放结点各域内容的地址

①生成结点变量的标准函数

p=( ListNode *)malloc(sizeof(ListNode))

//函数malloc分配一个类型为ListNode的结点变量的空间,并将其首地址放入指针变量p中

②释放结点变量空间的标准函数

free(p)//释放p所指的结点变量空间

③结点分量的访问

利用结点变量的名字*p访问结点分量

方法一:(*p).data和(*p).next

方法二:p->data和p->next

④指针变量p和结点变量*p的关系

指针变量p的值--结点地址

结点变量*p的值--结点内容

(*p).data的值--p指针所指结点的data域的值

(*p).next的值--*p后继结点的地址

*((*p).next)--*p后继结点

注意:

① 若指针变量p的值为空(NULL),则它不指向任何结点。此时,若通过*p来访问结点就意味着访问一个不存在的变量,从而引起程序的错误。

② 有关指针类型的意义和说明方式的详细解释

可见,在链表中插入结点只需要修改指针。但同时,若要在第 i 个结点之前插入元素,修改的是第 i-1 个结点的指针。

因此,在单链表中第 i 个结点之前进行插入的基本操作为:

找到线性表中第i-1个结点,然后修改其指向后继的指针。

#include<stdio.h>

#include<malloc.h>

#include<stdlib.h>

#define LEN sizeof(node)

typedef struct polynode /*用单链表存储多项式的结点结构*/

{

int coef /*多项式的系数*/

int exp /*指数*/

struct polynode *next/*next是struct polynode类型中的一个成员,它又指向

struct polynode类型的数据,以此建立链表*/

}node/*若定为"node,*list",意即node*与list同为结构指针类型*/

node * create(void) /*指针函数,返回指针类型;用尾插法建立一元多项式的链表的函数*/

{

node *h,*r,*s

int c,e

h=(node *)malloc(LEN) /*建立多项式的头结点,为头结点分配存储空间*/

r=h/*r指针始终动态指向链表的当前表尾,以便于做尾插入,其初值指向头结点*/

printf("coef:")

scanf("%d",&c)/*输入系数*/

printf("exp: ")

scanf("%d",&e)/*输入指针*/

while(c!=0) /*输入系数为0时,表示多项式的输入结束*/

{

s=(node *)malloc(LEN)/*申请新结点*/

s->coef=c /*申请新结点后赋值*/

s->exp=e /*申请新结点后赋值*/

r->next=s/*做尾插,插入新结点*/

r=s /*r始终指向单链表的表尾*/

printf("coef:")

scanf("%d",&c)

printf("exp: ")

scanf("%d",&e)

}

r->next=NULL/*将表的最后一个结点的next置NULL,以示表结束*/

return(h)

}

void polyadd(node *polya, node *polyb)/*一元多项式相加函数,用于将两个多项式相加,然后将和多项式存放在多项式polya中,并将多项式ployb删除*/

{

node *p,*q,*pre,*temp

int sum

p=polya->next/*令p和q分别指向polya和polyb多项式链表中的第一个结点*/

q=polyb->next

pre=polya /*位置指针,指向和多项式polya*/

while(p!=NULL&&q!=NULL) /*当两个多项式均未扫描结束时,执行以下操作*/

{

if(p->exp<q->exp) /*若p指向的多项式指数小于q指的指数*/

{

pre->next=p /*将p结点加入到和多项式中*/

pre=pre->next

p=p->next

}

else if(p->exp==q->exp)/*若指数相等,则相应的系数相加*/

{

sum=p->coef+q->coef

if(sum!=0)

{

p->coef=sum

pre->next=ppre=pre->nextp=p->next

temp=qq=q->nextfree(temp)

}

else /*如果系数和为零,则删除结点p与q,并将指针指向下一个结点*/

{

temp=p->nextfree(p)p=temp

temp=q->nextfree(q)q=temp

}

}

else /*若p指数大于q指数*/

{

pre->next=q /*p结点不动,将q结点加入到和多项式中*/

pre=pre->next

q=q->next

}

}

if(p!=NULL) /*多项式A中还有剩余,则将剩余的结点加入到和多项式中*/

pre->next=p

else/*否则将B的结点加入到和多项式中*/

pre->next=q

}

void print(node * p) /*输出函数,打印出一元多项式*/

{

while(p->next!=NULL)

{

p=p->next

printf(" %d*x^%d",p->coef,p->exp)

}

}

main() /*主函数*/

{

node * polya,* polyb

printf("Welcome to use!\n")

printf("\nPlease input the ploya include coef &&exp:\n")

polya=create() /*调用建立链表函数,创建多项式A*/

print(polya)

printf("\nPlease input the ployb include coef &&exp:\n")

polyb=create() /*同理,创建B*/

print(polyb)

printf("\nSum of the poly is:\n")

polyadd(polya,polyb) /*调用一元多项式相加函数*/

print(polya) /*调用输出函数,打印结果*/

printf("\n")