链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
单链表
以"结点的序列"表示线性表称作线性链表(单链表)
单链表是链式存取的结构,为找第 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")
你的代码很有问题啊。在VS2013上面跑都不能跑。
你的意思是如果不读取到May就一直往下读取建立链表吧。
帮你修改了一下。应该可以了。
测试环境:DevC++
测试程序
#include<stdio.h>#include<string.h>
#include"malloc.h"
#define len sizeof(link)
typedef struct linklist
{char a[4]
struct linklist *next
}link
main()
{
link *head=(link *)malloc(len)
link *p,*q
memset(head->a, '\0', sizeof(char)* 4)
head->next = NULL
scanf("%s",head->a)
q=head
while(strcmp(q->a,"May")!=0){
p=(link *)malloc(len)
q->next=p
q=p
scanf("%s",p->a)
}
p->next=NULL
}