链表是一种不要求连续存储空间的线性表,即存储单元可以是不连续的.
数据域 data 指针域 next
其中存储数据元素信息的域称作数据域(设域名为data),存储直接后继存储位置的域称为指针域(设域名为next)。指针域中存储的信息又称做指针或链。
由分别表示,,…, 的N 个结点依次相链构成的链表,称为线性表的链式存储表示,由于此类链表的每个结点中只包含一个指针域,故又称单链表或线性链表.
讲一下数据和链表的区别有可能帮助你对链表的使用有个感觉。
数组是将元素在内存中连续存放,由于每个元素占用内存相同,所以你可以通过下标迅速访问数组中任何元素。但是如果你要在数组中增加一个元素,你需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果你想删除一个元素,你同样需要移动大量元素去填掉被移动的元素。
链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。比如:上一个元素有个指针指到下一个元素,以此类推,直到最后一个元素。如果你要访问链表中一个元素,你需要从第一个元素开始,一直找到你需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了, 只要修改元素中的指针就可以了。
从上面的比较你可以看出,如果你的应用需要快速访问数据,很少或不插入和删除元素,你就应该用数组;相反, 如果你的应用需要经常插入和删除元素你就需要用链表数据结构了。然后你自己可以想一想什么样的应用用链表合适。
公共程序段代码:
#include "stdio.h"
#include "stdlib.h"
#define EOF '/r'
struct linked_list
{
char d;
struct linked_list *next;
}
struct linked_list *head;
struct linked_list *a,*b;
链表的基本操作
一.建立链表 (堆栈方式建立单链表,和队列方式建立单链表)
1.堆栈方式建立链表 /*后进先出
struct linked_list *createlink()
{
struct linked_list *p,*head;
char c;
head=NULL;
while((c=getche())!=EOF)
{
p=(struct linked_list)malloc(sizeof(struct linked_list)); //分配内存空间
p->d=c; //赋值
p->next=head; //指向前1个元素
head=p; //栈顶
}
return (head);
}
2.队列方式建立链表 /*先进先出
struct linked_list *qcreatelink()
{
struct linked_list *p,*head,*tail;
char c;
head=NULL;
while((c=getche()!=EOF)
{
p=(struct linked_list*)malloc(sizeof(struct linked_list));
p->d=c;
if(head==NULL)
{ head=p; tail=p; } //第1个元素为队列头,
else
{ tail->next=p; tail=p; } //tail->next=p指向下1个元素
}
tail->next=NULL; //最后个元素的下个元素为NULL
return (head);
}
二.计数和遍历
int count(head) /*计数:统计线性链表元素的个数
{
if(head==NULL)
return 0;
else
return (1+count(head->next));
}
printf_list(struct linked_list *p) /*使用递归的方法遍历并输出
{
if(p==NULL)
printf("NULL");
else
{
printf("%c--->",p->d);
print_list(p->next);
}
}
outlink(head) /*使用非递归方法遍历并输出
{
while(head)
{
printf("%c",head->d);
head=head->next;
}
}
三.线性链表的串接
concatenate(a,b) /* a必须不能为空
{
if(a->next==NULL) //把b接到a最后
a->next=b;
else
concatenate(a->next,b);
}
四.插入新的结点q
1.在表头插入
if(p1==head) //插入位置是否表头
{
q->next=head; //表头放在新结点之后
head=q; //新的表头
}
2.将新的结点插入到链表中间的任何两个结点之间
insert(p1,p2,q)
{
p1->next=q;
q->next=p2;
}
3.在表尾插入
if(p1->next==NULL)
{
p1->next=q;
q->next=NULL;
}
五.删除
delete_list(head)
{
if(head!=NULL) //不为空
{
delete_list(head->next); //递归删除
free(head); //删除
}
}