链表
链表也是一种线性表,与顺序表不同之处在于不像顺序表占据一段连续的存储空间,而是将存储单元分散在内存的任意地址上。
链表结构中,储存每个数据时候都会把记录写在链表的一个结点(node)中,每个结点之间由指针相连,形成如同链子的结构。
结点(node):可以是一个结构体类型元素,必须有一个专门来存放地址的域,用这个域来存放后继结点的地址,这样就连接起来
链表组成:通常有表头(指针变量,存放第一个结点地址),最后一个结点的指针域要空(NULL,因为没有后继结点)
实例分析
/********************************************
*从终端输入一组整数,以0为结束标志,存放链表中
*打印链表的值
*再删除顺序表中的第五个元素,打印出结果
*最后在内存中释放该链表
********************************************/
#include#include#define MaxSize 10
#include/* 定义一个结构体Sqlist */
typedef struct node{
int data; //数据域
struct node *next;//指针域
}LNode, *LinkList;
//自定义方式将结构定义为LNode类型 在定义一个指向LNode的指针类型变量
//LNode *L 等价于 LinkList L
/* 创建一个链表,包含n个结点(长度为n) */
/* 参数L:Sqlist类型的指针因为是指针所以可以在函数中直接对顺序表进行操作 */
LinkList myLinkList(int n){
LinkList p, r, list = NULL;
int e, i;
for(i = 1; i <= n; i++)
{
scanf("%d", &e);//输入结点的内容
p = (LinkList) malloc (sizeof(LNode));//为新建的结点开辟内存空间
p->data = e;//元素赋值
p->next = NULL;
if(!list)
list = p;//赋值链表头指针
else
r->next = p; //将结点连入链表
r = p;
}
return list;//返回链表头指针
}
/********************
*向链表中插入结点
*参数L :Sqlist类型的指针
*参数i:插入元素的位置
*参数item:插入的元素
*********************/
void insertList(LinkList *list, LinkList q, int e)
{
LinkList p;
p = (LinkList) malloc (sizeof(LNode));//为新建的结点开辟内存空间
p->data = e;//元素赋值
if(! *list){
*list = p;
p->next = NULL;
}
else{
p->next = q->next;
q->next = p;
}
}
/********************
*删除链表某结点
*参数L :Sqlist类型的指针
*参数i:删除元素的位置
*********************/
void delLink(LinkList *list, LinkList q)
{
LinkList r;
if(q == *list)//如果删除第一个结点
{
*list = q->next;
free(q);
}
else//删除其他结点
{
for(r = *list; r->next != q; r = r->next)
if(r->next != NULL)
{
r->next = q->next;
free(q);
}
}
}
/********************
*销毁一个链表
*参数L :Sqlist类型的指针
*参数i:删除元素的位置
*********************/
void destroyLinkList(LinkList *list)
{
LinkList p, q;
p = *list;
while(p)//循环释放每一个链表结点
{
q = p->next;
free(p);
p = q;
}
*list = NULL;
}
/********************
*测试函数
*********************/
int main()
{
int e, i;
LinkList l, q;
q = l = myLinkList(1);//创建一个链表结点,q和l指向该结点
scanf("%d" , &e);
while(e)
{
insertList(&l, q, e);
q = q->next;
scanf("%d" , &e);
}
q = l;
printf("链表内容为:\n");
while(q)
{
printf("%d" , q->data);
q = q->next;
}
q = l;
printf("删除第五个结点:\n");
for(i = 0; i < 4; i++)//指针q指向链表第五个元素
{
q = q->next;
}
delLink(&l, q);//删除q指向的结点
q = l;
while(q)//打印删除后的结果
{
printf("%d" , q->data);
q = q->next;
}
destroyLinkList(&l);//释放该链表
return 0;
}