链表结构
typedef struct Node{
int data;
struct Node* next;
};
链表初始化
List Init(List L)
{
L=(List)malloc(sizeof(struct Node));
L->data=0;
L->next=NULL;
}
链表的创建//带头节点
1.前插法创建链表
链表顺序与输入顺序相反
List CreatList(int n) //也可以是void,因为List是指针
{
List Head,Pre;
Head=(List)malloc(sizeof(struct Node));
Head->next=NULL;
while(n--)
{
Pre=(List)malloc(sizeof(struct Node));
scanf("%d",&Pre->data);
Pre->next=NULL;
Pre->next=Head->next;
Head->next=Pre;
}
return Head;
}
2.后插法创建链表
链表顺序与输入顺序相同
List CreatList(int n)
{
List Head,Rear,Pre;
Head=Rear=(List)malloc(sizeof(struct Node));
Head->next=NULL;
while(n--)
{
Pre=(List)malloc(sizeof(struct Node));//补:Pre->next=NULL;
scanf("%d",&Pre->data);
Rear->next=Pre;//Rear的下一个链接上Pre
Rear=Pre;//Rear指向Pre尾结点
}
return Head;
}
查找
1.按值查找
List find_elem(List L,int elem)
{
List tp=L;
while(tp&&tp->data!=elem)
{
tp=tp->next;
}
return tp;
}
2.按次序查找
List find_th(List L,int k)
{
int i=0;
List p=L;
while(i<k&&p->next) p=p->next;
if(p->next==NULL)
{
printf("位次错误");
return NULL;
}
return p;
}
删除
bool Delete(List L,int i)
{
int j=0;
List q,p=L;
while(p->next&&j<i-1)
{
p=p->next;
j++;
}
if(p->next==NULL||j>i-1) return false;
q=p->next;
p->next=q->next;
free(q);
return true;
}
插入
先断后连
bool Insert(List L,int e,int i)
{
List p=L,q;
int j=0;
while(p->next!=NULL&&j<i-1) p=p->next,j++;
if(p->next==NULL&&j>i-1) return false;
q=(List)malloc(sizeof(struct Node));
q->data=e;
q->next=p->next;
p->next=q;
return true;
}
例题:递增链表的插入
本题要求实现一个函数,在递增的整数序列链表(带头结点)中插入一个新整数,并保持该序列的有序性。
输入样例:
5
1 2 4 5 6
3
输出样例:
1 2 3 4 5 6
#include<bits/stdc++.h>
using namespace std;
typedef struct Node{
int data;
struct Node* next;
}*List;
int main(void)
{
List Head,Pre,Rear,Tmp;
int n,m,i;
Head=Rear=(List)malloc(sizeof(struct Node));
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
Pre=(List)malloc(sizeof(struct Node));
Pre->next=NULL;
scanf("%d",&Pre->data);
Rear->next=Pre;
Rear=Pre;
}
Pre=Head;
while(Pre->next!=NULL&&Pre->next->data<m) Pre=Pre->next;
Tmp=(List)malloc(sizeof(struct Node));
Tmp->data=m;
Tmp->next=NULL;
Tmp->next=Pre->next;
Pre->next=Tmp;
if(Pre==Rear) Rear=Tmp;
Tmp=Head->next;
printf("%d",Tmp->data);
for(Tmp=Tmp->next;Tmp!=NULL;Tmp=Tmp->next)
printf(" %d",Tmp->data);
return 0;
}
循环链表
特征:最后一个结点的指针域指向头结点,终止条件为p!=T或p->next!=L;
双链表
typedef struct DuNode{
int data;
struct DuNode* next;
struct DuNode* prior;
}*DuList;
双链表的建立
//尾插法建立双链表
void CreatDuList(int n)
{
int i,m;
DuList L,S,R;
L=(DuList)malloc(sizeof(struct DuNode));
L->next=NULL;
R=L;
for(i=0;i<n;i++)
{
scanf("%d",&m);
S=(DuList)malloc(sizeof(struct DuNode));
S->data=m;
R->next=S;
S->prior=R;
R=S;
}
R->next=NULL;
}
双向链表的查找
//按值查找
DuList find(DuList L,int n)
{
DuList p=L;
while(p&&p->data!=x) p=p->next;
return p;
}
//安次序查找
DuList find_th(DuList L,int i)
{
int j=0;
DuList p=L;
while(p&&j<i) p=p->next;
return p;
}
双向链表的插入
//插入
bool Insert(DuList L,int e,int n)
{
int j=0;
DuList p=L,s;
while(p->next&&j<n-1) p=p->next;
if(j>n-1||p->next==NULL) return false;
s=(DuList)malloc(sizeof(struct DuNode));
s->data=e;
s->next=p->next;
p->next->prior=s;
p->next=s;
s->prior=p;
return true;
}
双向链表的删除
//删除
bool Delete(DuList L,int i)
{
DuList p=L;
int j=0;
while(p->next&&j<i-1) p=p->next;
if(j>i-1||p->next==NULL)
{
printf("超出范围");
return false;
}
DuList tp=p->next;
p->next=tp->next;
tp->next->prior=p;
free(tp);
return true;
}