一、介绍
使用链表可以让我们动态的进行数据存储于分配,方便的实现数据的增加与删除。
链表中每个数据元素由指针域和数据域两个部分组成。其结构就是通过指针`链接`的线性表。
由于前后结点(数据元素)之间是单向链接的,所以称单向链表。
数据元素组织形式
typedef int datatype;
typedef struct node{
datatype data;
struct node *next;
}listnode,*linklist;
其中,listnode表示为链表类型,linklist表示为链表指针类型
定义结构体指针变量listnode *H;相当于linklist H;
二、相关函数操作
1.创建空链表
linklist list_create()
{
linklist H;
if((H=(linklist)malloc(sizeof(listnode)))==NULL)
{
printf("malloc failed!\n");
return H;
}
H->data = 0;
H->next = NULL;
return H;
}
2.遍历所有结点并显示
void list_show(linklist H)
{
while(H->next)
{
printf("%d ",H->next->data);
H = H->next;
}
printf("\n");
}
3.查询结点
按位置查询结点
linklist list_get(linklist H,int pos)
{
linklist p=H;
int i=-1;
if(pos<0)
{
printf("position is invalid:<0\n");
return NULL;
}
while(p->next && i<pos)
{
p=p->next;
i++;
}
//if(p->next)
if(i==pos)
{
return p;
}
else
{
printf("position is invalid: > length\n");
return NULL;
}
}
4.插入结点
头部(首节点)插入
int list_head_insert(linklist H,datatype value)
{
linklist p;
if((p=(linklist)malloc(sizeof(listnode)))==NULL)
{
printf("malloc failed\n");
return -1;
}
p->data = value;
p->next = H->next;
H->next = p;
return 0;
}
p->next = H->next; //待插入的结点指向H的下一个结点
H->next = p; //H指向待插入的结点
末尾插入(同时初始化)
linklist list_create2()
{
linklist H,r,p;
int value;
if((H=(linklist)malloc(sizeof(listnode)))==NULL)
{
printf("malloc failed!\n");
return H;
}
H->data = 0;
H->next = NULL;
r=H;
while(1)
{
printf("input a number(-1 exit):");
scanf("%d",&value);
if(value == -1)
break;
if((p=(linklist)malloc(sizeof(listnode)))==NULL)
{
printf("malloc failed\n");
return H;
}
p->data = value;
p->next = NULL;
r->next = p;
r=p;
}
return H;
}
按位置插入
int list_insert(linklist H,int pos,datatype value)
{
linklist p,q;
if(pos==0)
p=H;
else
p=list_get(H,pos-1);
if(p==NULL)
{
printf("para is invalid\n");
return -1;
}
else
{
if((q=(linklist)malloc(sizeof(listnode)))==NULL)
{
printf("malloc failed\n");
return -1;
}
q->data = value;
q->next = p->next;
p->next = q;
return 0;
}
}
根据结点数据从小到大的规律插入结点
int list_order_insert(linklist H,datatype value)
{
linklist p,q;
if((p=(linklist)malloc(sizeof(listnode)))==NULL)
{
printf("malloc faied\n");
return -1;
}
p->data = value;
q=H;
while(q->next&&q->next->data < value)
{
q=q->next;
}
p->next = q->next;
q->next = p;
return 0;
}
5.删除结点
int list_delete(linklist H,int pos)
{
linklist p,q;
if(pos == 0)
p=H;
else
p=list_get(H,pos-1);
if(p==NULL || p->next==NULL)
{
printf("para is invalid\n");
return -1;
}
else
{
q=p->next;
p->next=q->next;
free(q);
q=NULL;
return 0;
}
}
6.倒置链表
void list_reverse(linklist H)
{
linklist p,q;
p=H->next;
H->next = NULL;
while(p)
{
q=p;
p=p->next;
q->next = H->next;
H->next = q;
}
}
7.排序链表结点(从小到大)
void list_sort(linklist H)
{
linklist p,q,r;
p=H->next;
H->next = NULL;
while(p)
{
q=p;
p=p->next;
r=H;
while(r->next && r->next->data < q->data)
r=r->next;
q->next = r->next;
r->next = q;
}
}
每次循环执行一次插入(最后一次比较的结果),将p->next 指向结点插入到r->next 指向结点和r 指向结点之间