
1。是由结构体和指针构成的。
2。包括两个部分一个是数据域和指针域。
3。链表中的结点分为两类:头结点和一般结点。头结点是没有数据域的。
4。基本 *** 作有:初始化链表,增加结点和删除结点,求链表的长度等等。
struct Linknode{
int data;
struct Linknode next;
};
这个地方有个知识点:这个是链表的数据结构是有结构体和指针构成。结构体名为Linknode但这里面没有定义结构体变量,只有我们定义了结构体变量才能使用结构体。
结构体变量怎么定义呢?
有两种方式:
1。struct Linknode Linklist;
2typedef struct linknode Linklist
一般我们都希望采用第2种,这样的好处是: 当我们再定义结构体变量时,可以用:Linklist p;而如果我们采用第一种还必须采用 struct Linknode p;对比一下就可以知道第2种要简单很多。那么下面我们都采用第2种方式来定义结构体变量。
上面我们已经定义了一个链表:
1。初始化链表。
#include
#include
int InitLinkList(Linklist Lnode)
{
Lnode=(Linklist)malloc(sizeof(Linklist));//Lnode等于L,对与Lnode的分配空间相当与对主函数中的L分配空间。
if(!Lnode)
return 0;
(Lnode)->next=NULL;
}
在初始化链表的时候,我们用到了2级指针为什么呢?因为我们希望在InitLinkList函数生成的头结点,主函数中也能指向这个头结点。如果我们用一级指针的话,用malloc分配空间的时候,它将会返回分配空间的首地址给指针变量Lnode,而不能使是的空间被主函数中指针变量L得到这个地址。所以我们要用2级指针。
void main()
{
Linklist L;
InitLikList(&L);
}
2。增加链表结点
增加链表结点其实很简单,一般用到三个结构体指针变量和一个循环结构。
InsertLinkList(Linklist Lnode)
{
Linklist p,q;
int d;
{
scanf("%d",&d);
if(d==-9999)
break;
p=Lnode->next;//p指向头结点
//通过while循环和指针变量p定位要插入的结点q的位置。
while(p)
p=p->next;
//生成一个要插入的结点
q=(Linklist)malloc(sizeof(Linklist));//申请要插入的结点空间
q->data=d;//填充要插入结点的数据域
q->next=p->next;//首先填充要插入结点q的指针域进行填充。
p->next=q;//然后把定位好的p指针域进行修改指向q
}while(9);//循环退出的条件是输入的数据-9999
}
void main()
{
Linklist L;
InitLinkList(&L);//生成一个头结点
InsertLinkList(L);//插入结点
}
3。求链表的长度:
int LengthLinkList(Linklist Lnode)
{
int i=0;
Linklist p;
p=Lnode->next;//p指向链表的第一个结点。
while(p)
{
i++;
p=p->next;
}
return i;
}
void main()
{
Linklist L;
InitLinkList(&L);//生成一个头结点
InsertLinkList(L);//插入一个结点
LengthLinkList(L)//求链表的长度。
}
4删除结点
删除链表结点其实很简单,一般用到三个结构体指针变量和一个循环结构。
DestroyLinkList(Linklist Lnode)
{
Linklist p,q;
p=Lnode;//p指向链表的头结点
while(p)
{
q=p->next;//q指向当前结点的下一个结点。
free(p);//释放当前结点
p=q;//p指向下一个结点
}
}
void main()
{
Linklist L;
InitLinkList(&L);//生成一个头结点
InsertLinkList(L);//插入结点
LengthLinkList(L)//求链表的长度。
DestroyLinkList(L);//删除链表结点
}
函数main()里的语句 LinkList L; 系统自动给变量L分配了内存,
L对应的是第2个结构体,也就是LinkList
调用初始化函数InitList(),给变量L里的成员head,tail,len进行赋值,
Lhead指向的就是空链表,此时,Lhead=NULL,同时,Llen=0,表示没有结点
所以执行函数InitList()之后,也就制造了空链表
执行函数InsertNode()之后,链表就加入了新结点, 结点对应的是第1个结构体,也就是LNode
Lhead指向链表的头结点, Ltail指向链表的末尾结点, Llen表示结点的数量
测试结果:
初始化之后,链表长度是 0
插入数据之后,链表长度是 3
链表里的数据是: 10 20 30
//代码用了"引用"(&),所以要用C++编译器进行测试
#include<stdioh>
#include<stdlibh>
typedef int ElemType;
typedef int Status;
typedef struct LNode
{
ElemType data;
struct LNode next;
}Link, Position;
typedef struct
{
Link head,tail;
int len;
}LinkList;
Status InitList(LinkList &L);
Status InsertNode(LinkList &L,ElemType e);
Status ListTraverse(LinkList L);
int ListLength(LinkList L);
//链表初始化
Status InitList(LinkList &L) //&是"引用"符号
{
Lhead = NULL;
Ltail = NULL;
Llen = 0;
return 1;
}
//插入结点
Status InsertNode(LinkList &L,ElemType e) //&是"引用"符号
{
LNode newNode;
newNode=(LNode )malloc(sizeof(LNode));
if(newNode==NULL)
{
printf("\n分配内存错误\n");
exit(1);
}
newNode->data = e;
newNode->next = NULL;
//用"尾插法"添加新结点
if(Lhead==NULL)
{
Lhead = newNode;
Ltail = newNode;
Llen = 1;
}
else
{
Ltail->next = newNode;
Ltail = newNode;
Llen = Llen+1;
}
return 1;
}
//链表遍历
Status ListTraverse(LinkList L)
{
Link p;
p = Lhead;
if(p == NULL)
{
printf("\n链表为空\n");
return 0;
}
while(p != NULL)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
return 1;
}
//链表长度
int ListLength(LinkList L)
{
return Llen;
}
int main()
{
LinkList L;
InitList(L);
printf("初始化之后,链表长度是 %d\n",ListLength(L));
InsertNode(L,10);
InsertNode(L,20);
InsertNode(L,30);
printf("插入数据之后,链表长度是 %d\n",ListLength(L));
printf("链表里的数据是: ");
ListTraverse(L);
return 0;
}
你看看你怎么定义你的creat函数的?
struct number creat()
{
}
这里你分明没有指定creat的形参,默认当然就不能接受实参。但是你在main函数中调用的时候
head1=creat(a1);
却又硬给creat函数塞进去一个实参a1,这下当然就消化不良咯。所以办法有两个,要么你给creat函数加上形参,不过我似乎没有发现你的creat函数有使用形参的行为;要么,修改你的main函数,把实参去掉。
还有,main函数中有这句
head=insert(a1,a2);
a1和a2分明是两个int型变量,可是你的insert函数的形参类型却要求是结构体指针,这个我不知道你是怎么考虑的。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)