线性表的链式存储结构,是用一组任意的存储单元(这组存储单元的地址可以连续,也可以不连续)来存放线性表中的各个数据元素的。
存放数据元素信息的域data称作数据域,存放后继元素地址信息的域称作指针域或链域。
特征: 每个结点只含有一个指向后继的指针
循环链表: 表中最后一个结点的指针域指向头结点,使整个链表构成一个环,可以从表中任一结点出发访问遍所有结点(遍历)。
双向链表: 增加一个指针域存储前趋信息,每个结点就有两个方向不同的链。让每条链都构成一个环,称为双向循环链表。双向链表是一种对称结构,每个结点都既有指向其前趋的指针,也有指向其后继的指针;每个结点的地址既放在其后继结点的前趋域中,也放在其前趋结点的后继域中。
单链表算法:
创建链表初始化链表
typedef struct node
{
int data;
struct node *pNext;
}NODE,* PNODE;
PNODE create_list()
{
int len,val,i;
printf("请输入链表的长度 len=");
scanf("%d",&len);
PNODE phead=(PNODE)malloc(sizeof(NODE));
if(phead==NULL)
{
printf("内存分配失败");
exit(-1);
}
PNODE ptail=phead;
ptail->pNext=NULL;
for(i=0;i<len;i++)
{
PNODE pnew=(PNODE)malloc(sizeof(NODE));
if(pnew==NULL)
{
printf("内存分配失败");
exit(-1);
}
printf("请输入第%d个节点的值",i+1);
scanf("%d",&val);
pnew->data=val;
ptail->pNext=pnew;
pnew->pNext=NULL;
ptail=pnew;
}
return phead;
}
遍历链表
void traverse_list(PNODE phead)
{
PNODE p=head->pNext;
while(p!=NULL)
{
printf("%d\t",p->data);
p=p->pNext;
}
printf("\n");
}
链表元素个数
int len_list(PNODE phead)
{
PNODE p=phead->pNext;
int len=0;
while(p!=NULL)
{
p=p->pNext;
len++;
}
return len;
}
删除指定节点
void delete_list(PNODE phead)
{
int i=0,pos;
PNODE p=head;
printf("请输入要删除的值的位置:");
scanf("%d",&pos);
while(p->pNext!=NULL && i<pos-1)
{
p=p->pNext;
i++;
}
if(p->pNext==NULL || i>pos-1)
{
printf("输入位置有误\n");
delete_list(phead);
return;
}
PNODE q=p->pNext;
p->pNext=p->pNext->pNext;
printf("删除%d成功\n",q->data);
free(q);
q=NULL;
traverse_list(phead);
}
插入节点
void insert_list(PNODE phead)
{
int pos,i=0;
PNODE p=phead;
printf("请输入要插入的位置:");
scanf("%d",&pos);
while(p->pNext!=NULL && i<pos-1)
{
p=p->pNext;
i++;
}
if(p->pNext==NULL || i>pos-1)
{
printf("输入位置有误\n");
insert_list(phead);
return;
}
PNODE pnew=(PNODE)malloc(sizeof(NODE));
if(pnew==NULL)
{
printf("内存分配失败");
exit(-1);
}
int data;
printf("请输入要插入的数值:");
scanf("%d",&data);
pnew->data=data;
pnew->pNext=p->pNext;
p->pNext=pnew;
traverse_list(phead);
}