在单链表中,每一个结点包含两部分:存放每一个数据元素本身信息的数据域和存放其直接后继存储位置的指针域。
单链表结点的类型描述:
typedef int ElemType;
typedef struct node{
ElemType data;
struct node *next;
}LNode,*LinkList;
单链表的存取必须从头指针开始进行,因此,通常用头指针来标识一个单链表。若头指针为空,则表示空链表。有时,在单链表的第一个结点之前附设一个结点,称之为头结点。
单链表的操作:
1. 单链表的初始化Init_LinkList()
单链表的初始化是建立带头结点的空链表
//初始化运算
LinkList Init_LinkList(){
LinkList L;
L = (LinkList)malloc(sizeof(LNode));
L->next=NULL;
return L;
}
2. 求单链表的长度Length_LinkList(LinkList L)
//求表长运算
int Length_LinkList(LinkList L){
LinkList p;
int length = 0;
p = L->next;//p指向第一个结点
while(p){
length++;
p = p->next;
}
return length;
}
3. 按序号查找单链表Locate_LinkList_BySeq(LinkList L,int i)
从链表的头指针出发,逐个向后扫描,直到扫描到第i个结点为止。
//按序号定位
LinkList Locate_LinkList_BySeq(LinkList L,int i){
LinkList p = L;
int j = 0;
while(j < i && p->next){
p = p->next;
j++;
}
if(j == i)
return p;
else
return NULL;
}
4. 按值查找单链表Locate_LinkList_ByValue(LinkList L,ElemType e)
从单链表的第i个结点起,顺序扫描单链表,将结点的值和e相比较,直到找到一个和e相等的结点为止,返回该结点的指针;否则,若查遍整个链表找不到这样的结点,则返回空指针。
//按值定位
LinkList Locate_LinkList_ByValue(LinkList L,ElemType e){
LinkList p = L->next;
while(p != NULL && p->data != e){
p = p->next;
}
return p;
}
5. 将新结点*s插入到结点*p之后的运算InsertAfter(LinkList p,ElemType e)
//将新结点插入到指定结点之后
void InsertAfter(LinkList p,ElemType e){
LinkList s;
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
}
6. 将新结点*s插入到结点*p之前InsertBefore(LinkList L,LinkList p,ElemType e)
//将新结点插入到指定结点之前
void InsertBefore(LinkList L,LinkList p,ElemType e){
LinkList s,q;
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
q = L;
//找到p的前驱结点
while(q->next != p)
q = q->next;
s->next = p;
q->next = s;
}
7. 在单链表第i个结点之前插入新结点
//将新结点插入到第i个结点之前
void InsertBefore_Seqi(LinkList L,int i,ElemType e){
LinkList p,s;
//找到第i-1个结点
p = Locate_LinkList_BySeq(L,i-1);
if(p == NULL)
printf("i位置不合法");
else{
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
}
}
8. 在单链表第i个结点之后插入新结点
//将新结点插入到第i个结点之后
void InsertAfter_Seqi(LinkList L,int i,ElemType e){
LinkList p,s;
//找到第i个结点
p = Locate_LinkList_BySeq(L,i);
if(p == NULL)
printf("i位置不合法");
else{
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
}
}
9. 删除*p结点的后继结点DeleteAfter_Nodep(LinkList p)
//删除*p结点的后继结点
void DeleteAfter_Nodep(LinkList p){
LinkList s;
if(p->next == NULL)
printf("当前结点的后继结点为空\n");
else{
s = p->next;
p->next = s->next;
free(s);
}
}
10. 删除*p结点DeleteNodep(LinkList L,LinkList p)
//删除指定结点
void DeleteNodep(LinkList L,LinkList p){
LinkList q;
q = L;
//找到*p的前驱结点
while(q->next != p)
q = q->next;
q->next = p->next;
free(p);
}
11. 删除单链表的第i个结点Delete_Nodei(LinkList L,int i)
//删除单链表的第i个结点
void Delete_Nodei(LinkList L,int i){
LinkList q,p;
//找到第i个结点
q = Locate_LinkList_BySeq(L,i-1);
if(q == NULL)
printf("第i-1个结点不存在\n");
else{
p = q->next;
q->next = p->next;
free(p);
}
}
12. 删除单链表中所有值为e的结点,并返回值为e的结点的个数Delete_Node_Valuee(LinkList L,ElemType e)
//删除单链表中所有值为e的结点,并返回值为e的结点的个数
int Delete_Node_Valuee(LinkList L,ElemType e){
LinkList q,p;
int count = 0;
q = L;
while(q->next != NULL){
p = q->next;
if(p->data == e){
q->next = p->next;
free(p);
}
else
q = p;
}
return count;
}
13. 输出单链表Print_LinkList(LinkList L)
//打印链表
void Print_LinkList(LinkList L){
LinkList p = L->next;
while(p){
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
}
14. 头插法建立单链表Create_LinkListF(int n)
//头插法建立单链表
LinkList Create_LinkListF(int n){
LinkList L,s;
int i,x;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
for(i=n;i>0;i--){
scanf("%d",&x);
s = (LinkList)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
L->next = s;
}
return L;
}
15. 尾插法建立单链表Create_LinkListR(int n)
//尾插法建立单链表
LinkList Create_LinkListR(int n){
LinkList L,s,p;
int i,x;
L = (LinkList)malloc(sizeof(LNode));
p = L;
for(i = n;i > 0;i--){
scanf("%d",&x);
s = (LinkList)malloc(sizeof(LNode));
s->data = x;
p->next = s;
p = s;
}
p->next = NULL;
return L;
}