一、单链表的定义和表示
线性表链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。因此,为了表示每个元素与其直接后继数据元素之间的逻辑关系,对数据元素来说,除了存储其本身的信息之外,还需要存储一个指示其直接后继的信息。这两部分信息组成数据元素的存储映像,称为结点。它包括两个域:
数据域:存储数据元素信息的域
指针域:存储直接后继存储位置的域
n个结点链结成一个链表,即为线性表的链式存储结构,而每个结点只包含一个指针域称为线性链表或单链表。
根据链表结点所含指针个数、指针指向和指针连接方式,可将链表分为单链表、循环链表、双向链表、二叉链表、十字链表、临近链表、临接多重表等。
首元结点:链表中存储第一个数据元素的结点
头结点:在首元结点之前附设的一个结点,其指针域指向首元结点。头节点的数据域一般存放链表的长度
头指针:指向链表中第一个结点的指针
注意:链表的最后一个结点的指针域为NULL
二、单链表的存储结构
typedef int ElemType; //重定义数据域的数据类型
typedef struct LNode //定义单链表存储结构
{
ElemType data; //结点的数据域
struct LNode *next;//结点的指针域
}*LinkList; //LinkList为指向结构体LNode的指针类型
三、单链表的操作
3.1 单链表创建
LinkList Request_space() //在堆区申请一个结点空间
{
LinkList node=(LinkList)malloc(sizeof(struct LNode)); //在使用malloc函数时,记得引用头文件#include <stdlib.h>
if(NULL==node)
return NULL;
node->data=0;
node->next=NULL;
return node;
}
3.2 单链表头插
LinkList insert_head(LinkList L_list,ElemType value) //实现头插
{
LinkList node=Request_space();
if(NULL==node)
return NULL;
node->data=value;
node->next=L_list;
L_list=node;
return L_list;
}
3.3 单链表尾插
LinkList insert_rear(LinkList L_list,ElemType value) //实现尾插
{
LinkList node=Request_space();
node->data=value;
if(NULL==L_list)
L_list=node;
else
{
LinkList rear=L_list;
while(rear->next!=NULL)
rear=rear->next;
rear->next=node;
}
return L_list;
}
3.4 单链表头删
LinkList delete_head(LinkList L_list) //实现头删
{
if(NULL==L_list)
return NULL;
if(L_list->next==NULL)
{
free(L_list);
L_list=NULL;
}
else
{
LinkList p=L_list->next;
L_list->data=p->data;
L_list->next=p->next;
free(p);
p=NULL;
}
return L_list;
}
3.5 单链表尾删
LinkList delete_rear(LinkList L_list) //实现尾删
{
if(NULL==L_list)
return NULL;
if(L_list->next==NULL)
{
free(L_list);
L_list=NULL;
}
else
{
LinkList rear=L_list;
while(rear->next->next!=NULL)
rear=rear->next;
free(rear->next);
rear->next=NULL;
}
return L_list;
}
3.6 单链表遍历
int Output(LinkList L_list) //实现输出
{
if(NULL==L_list)
return -1;
while(L_list!=NULL)
{
printf("%d ",L_list->data);
L_list=L_list->next;
}
puts("");
return 0;
}
3.7 计算单链表长度
int len_Llist(LinkList L_list) //计算单链表长度
{
int count=0;
if(NULL==L_list)
return -1;
while(L_list!=NULL)
{
count++;
L_list=L_list->next;
}
return count;
}
3.8 单链表任意位置插入
LinkList insert_by_seat(LinkList L_list,int seat,ElemType value) //实现任意位置插入
{
int len=len_Llist(L_list);
if(NULL==L_list||seat<1||seat>len+1)
return L_list;
if(seat==len+1)
L_list=insert_rear(L_list,value);
LinkList rear=L_list;
LinkList node=Request_space();
for(int i=1;i<seat;i++)
rear=rear->next;
node->data=rear->data;
rear->data=value;
node->next=rear->next;
rear->next=node;
return L_list;
}
3.9 单链表任意位置查找
int search_by_seat(LinkList L_list,int seat) //实现任意位置查找
{
int len=len_Llist(L_list);
if(NULL==L_list||seat<1||seat>len+1)
return -1;
LinkList rear=L_list;
for(int i=1;i<seat;i++)
rear=rear->next;
printf("%d\n",rear->data);
return 0;
}
3.10 单链表任意位置修改
int modify_by_seat(LinkList L_list,int seat,ElemType value) //任意位置修改
{
int len=len_Llist(L_list);
if(NULL==L_list||seat<1||seat>len+1)
return -1;
LinkList rear=L_list;
for(int i=1;i<seat;i++)
rear=rear->next;
rear->data=value;
return 0;
}
3.11 单链表任意位置删除
LinkList delete_by_seat(LinkList L_list,int seat) //任意位置删除
{
int len=len_Llist(L_list);
if(NULL==L_list||seat<1||seat>len)
return L_list;
if(seat==1)
L_list=delete_head(L_list);
else
{
LinkList rear=L_list;
for(int i=1;i<seat-1;i++)
rear=rear->next;
LinkList p=rear->next;
rear->next=p->next;
free(p);
p=NULL;
}
return L_list;
}
3.12 单链表任意元素查找
int search_by_element(LinkList L_list,ElemType value) //任意元素查找
{
if(NULL==L_list)
return -1;
int seat=0;
while(L_list)
{
seat++;
if(L_list->data==value)
return seat;
L_list=L_list->next;
}
return -1;
}
3.13 单链表任意元素删除
LinkList delete_by_element(LinkList L_list,ElemType value) //任意元素删除
{
int seat=search_by_element(L_list,value);
if(seat==-1)
return L_list;
L_list=delete_by_seat(L_list,seat);
return L_list;
}
3.14 单链表任意元素插入
LinkList insert_by_element(LinkList L_list,ElemType value,ElemType element) //任意元素插入
{
int seat=search_by_element(L_list,value);
if(seat==-1)
return L_list;
L_list=insert_by_seat(L_list,seat,element);
}
3.15 任意元素修改
int modify_by_element(LinkList L_list,ElemType value,ElemType element) //任意元素修改
{
int seat=search_by_element(L_list,value);
if(seat==-1)
return -1;
while(--seat)
L_list=L_list->next;
L_list->data=element;
return 0;
}
3.16 单链表逆置
LinkList rev_list(LinkList L_list) //单链表逆置
{
if(NULL==L_list||L_list->next==NULL)
return L_list;
LinkList p=L_list->next;
int len=len_Llist(L_list)-1;
L_list->next=NULL;
for(int i=0;i<len;i++)
{
LinkList q=p;
p=p->next;
q->next=L_list;
L_list=q;
}
return L_list;
}
3.17 释放单链表
LinkList free_space(LinkList L_list) //释放单链表
{
if(NULL==L_list)
return L_list;
int len=len_Llist(L_list);
for(int i=0;i<len;i++)
L_list=delete_head(L_list);
return L_list;
}
3.18 冒泡排序单链表
int Bubble_list(LinkList L_list) //冒泡排序单链表
{
if(NULL==L_list||L_list->next==NULL)
return -1;
int len=len_Llist(L_list);
int count,i,j;
LinkList p=L_list;
for(i=1;i<len;i++)
{
count=0;
for(j=0,p=L_list;j<len-i;j++,p=p->next)
{
if(p->data>p->next->data)
{
ElemType temp=p->data;
p->data=p->next->data;
p->next->data=temp;
count++;
}
}
if(count==0)break;
}
return 0;
}
3.19 简单选择排序单链表
int simple_list(LinkList L_list) //简单选择排序单链表
{
if(NULL==L_list||L_list->next==NULL)
return -1;
int len=len_Llist(L_list);
int i,j,seat;
LinkList p=L_list;
LinkList q=L_list;
for(i=0;i<len-1;i++,q=q->next)
{
seat=i;
for(j=i+1,p=q->next;j<len;j++,p=p->next)
{
if(q->data>p->data)
{
seat=j;
}
}
if(seat!=i)
{
p=L_list->next;
while(--seat)
p=p->next;
ElemType temp=q->data;
q->data=p->data;
p->data=temp;
}
}
return 0;
}
3.20 简单选择排序单链表2
int simple_list(Linklist L_list)
{
if(NULL==L_list||L_list->next==NULL)
return -1;
int len=Len_linklist(L_list);
Linklist p,q;
int i,j;
for(i=0,p=L_list;i<len-1;i++,p=p->next)
{
Linklist min=p;
for(j=i+1,q=p->next;j<len;j++,q=q->next)
{
if(min->data<q->data)
{
min=q;
}
}
if(min!=p)
{
int t=min->data;min->data=p->data;
p->data=t;
}
}
return 0;
}
四、多文件编辑实现单链表操作
头文件 head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int ElemType; //重定义数据域的数据类型
typedef struct LNode //定义单链表存储结构
{
ElemType data;
struct LNode *next;
}*LinkList;
LinkList Request_space(); //在堆区申请一个结点空间
int Output(LinkList L_list); //实现输出
LinkList insert_head(LinkList L_list,ElemType value); //实现头插
LinkList insert_rear(LinkList L_list,ElemType value); //实现尾插
LinkList delete_head(LinkList L_list); //实现头删
LinkList delete_rear(LinkList L_list); //实现尾删
LinkList insert_by_seat(LinkList L_list,int seat,ElemType value); //实现任意位置插入
int search_by_seat(LinkList L_list,int seat); //实现任意位置查找
int modify_by_seat(LinkList L_list,int seat,ElemType value); //任意位置修改
LinkList delete_by_seat(LinkList L_list,int seat); //任意位置删除
int search_by_element(LinkList L_list,ElemType value); //任意元素查找
LinkList delete_by_element(LinkList L_list,ElemType value); //任意元素删除
LinkList insert_by_element(LinkList L_list,ElemType value,ElemType element); //任意元素插入
int modify_by_element(LinkList L_list,ElemType value,ElemType element); //任意元素修改
LinkList rev_list(LinkList L_list); //单链表逆置
LinkList free_space(LinkList L_list); //释放单链表
int Bubble_list(LinkList L_list); //冒泡排序单链表
int simple_list(LinkList L_list); //简单选择排序单链表
#endif
自定义函数 fun.c
#include "head.h"
LinkList Request_space() //在堆区申请一个结点空间
{
LinkList node=(LinkList)malloc(sizeof(struct LNode));
if(NULL==node)
return NULL;
node->data=0;
node->next=NULL;
return node;
}
int Output(LinkList L_list) //实现输出
{
if(NULL==L_list)
return -1;
while(L_list!=NULL)
{
printf("%d ",L_list->data);
L_list=L_list->next;
}
puts("");
return 0;
}
LinkList insert_head(LinkList L_list,ElemType value) //实现头插
{
LinkList node=Request_space();
if(NULL==node)
return NULL;
node->data=value;
node->next=L_list;
L_list=node;
return L_list;
}
LinkList insert_rear(LinkList L_list,ElemType value) //实现尾插
{
LinkList node=Request_space();
node->data=value;
if(NULL==L_list)
L_list=node;
else
{
LinkList rear=L_list;
while(rear->next!=NULL)
rear=rear->next;
rear->next=node;
}
return L_list;
}
LinkList delete_head(LinkList L_list) //实现头删
{
if(NULL==L_list)
return NULL;
if(L_list->next==NULL)
{
free(L_list);
L_list=NULL;
}
else
{
LinkList p=L_list->next;
L_list->data=p->data;
L_list->next=p->next;
free(p);
p=NULL;
}
return L_list;
}
LinkList delete_rear(LinkList L_list) //实现尾删
{
if(NULL==L_list)
return NULL;
if(L_list->next==NULL)
{
free(L_list);
L_list=NULL;
}
else
{
LinkList rear=L_list;
while(rear->next->next!=NULL)
rear=rear->next;
free(rear->next);
rear->next=NULL;
}
return L_list;
}
int len_Llist(LinkList L_list) //计算单链表长度
{
int count=0;
if(NULL==L_list)
return -1;
while(L_list!=NULL)
{
count++;
L_list=L_list->next;
}
return count;
}
LinkList insert_by_seat(LinkList L_list,int seat,ElemType value) //实现任意位置插入
{
int len=len_Llist(L_list);
if(NULL==L_list||seat<1||seat>len+1)
return L_list;
if(seat==len+1)
L_list=insert_rear(L_list,value);
else
{
LinkList rear=L_list;
LinkList node=Request_space();
for(int i=1;i<seat;i++)
rear=rear->next;
node->data=rear->data;
rear->data=value;
node->next=rear->next;
rear->next=node;
}
return L_list;
}
LinkList delete_by_seat(LinkList L_list,int seat) //任意位置删除
{
int len=len_Llist(L_list);
if(NULL==L_list||seat<1||seat>len)
return L_list;
if(seat==1)
L_list=delete_head(L_list);
else
{
LinkList rear=L_list;
for(int i=1;i<seat-1;i++)
rear=rear->next;
LinkList p=rear->next;
rear->next=p->next;
free(p);
p=NULL;
}
return L_list;
}
int search_by_seat(LinkList L_list,int seat) //实现任意位置查找
{
int len=len_Llist(L_list);
if(NULL==L_list||seat<1||seat>len+1)
return -1;
LinkList rear=L_list;
for(int i=1;i<seat;i++)
rear=rear->next;
printf("%d\n",rear->data);
return 0;
}
int modify_by_seat(LinkList L_list,int seat,ElemType value) //任意位置修改
{
int len=len_Llist(L_list);
if(NULL==L_list||seat<1||seat>len+1)
return -1;
LinkList rear=L_list;
for(int i=1;i<seat;i++)
rear=rear->next;
rear->data=value;
return 0;
}
int search_by_element(LinkList L_list,ElemType value) //任意元素查找
{
if(NULL==L_list)
return -1;
int seat=0;
while(L_list)
{
seat++;
if(L_list->data==value)
return seat;
L_list=L_list->next;
}
return -1;
}
LinkList delete_by_element(LinkList L_list,ElemType value) //任意元素删除
{
int seat=search_by_element(L_list,value);
if(seat==-1)
return L_list;
L_list=delete_by_seat(L_list,seat);
return L_list;
}
LinkList insert_by_element(LinkList L_list,ElemType value,ElemType element) //任意元素插入
{
int seat=search_by_element(L_list,value);
if(seat==-1)
return L_list;
L_list=insert_by_seat(L_list,seat,element);
}
int modify_by_element(LinkList L_list,ElemType value,ElemType element) //任意元素修改
{
int seat=search_by_element(L_list,value);
if(seat==-1)
return -1;
while(--seat)
L_list=L_list->next;
L_list->data=element;
return 0;
}
LinkList rev_list(LinkList L_list) //单链表逆置
{
if(NULL==L_list||L_list->next==NULL)
return L_list;
LinkList p=L_list->next;
int len=len_Llist(L_list)-1;
L_list->next=NULL;
for(int i=0;i<len;i++)
{
LinkList q=p;
p=p->next;
q->next=L_list;
L_list=q;
}
return L_list;
}
LinkList free_space(LinkList L_list) //释放单链表
{
if(NULL==L_list)
return L_list;
int len=len_Llist(L_list);
for(int i=0;i<len;i++)
L_list=delete_head(L_list);
return L_list;
}
int Bubble_list(LinkList L_list) //冒泡排序单链表
{
if(NULL==L_list||L_list->next==NULL)
return -1;
int len=len_Llist(L_list);
int count,i,j;
LinkList p=L_list;
for(i=1;i<len;i++)
{
count=0;
for(j=0,p=L_list;j<len-i;j++,p=p->next)
{
if(p->data>p->next->data)
{
ElemType temp=p->data;
p->data=p->next->data;
p->next->data=temp;
count++;
}
}
if(count==0)break;
}
return 0;
}
int simple_list(LinkList L_list) //简单选择排序单链表
{
if(NULL==L_list||L_list->next==NULL)
return -1;
int len=len_Llist(L_list);
int i,j,seat;
LinkList p=L_list;
LinkList q=L_list;
for(i=0;i<len-1;i++,q=q->next)
{
seat=i;
for(j=i+1,p=q->next;j<len;j++,p=p->next)
{
if(q->data>p->data)
{
seat=j;
}
}
if(seat!=i)
{
p=L_list->next;
while(--seat)
p=p->next;
ElemType temp=q->data;
q->data=p->data;
p->data=temp;
}
}
return 0;
}
主函数 main.c
#include "head.h"
int main(int argc, const char *argv[])
{
LinkList L_list=NULL; //定义结点变量,注意定义时一定要指向NULL
int n; //定义循环输入次数
ElemType value; //定义数据域元素
int seat; //定义元素位置
printf("please enter n:");
scanf("%d",&n);
for(int i=0;i<n;i++) //头插
{
printf("please enter a value:");
scanf("%d",&value);
L_list=insert_head(L_list,value);
}
for(int i=0;i<n;i++) //尾插
{
printf("please enter a value:");
scanf("%d",&value);
L_list=insert_rear(L_list,value);
}
Output(L_list);
//任意位置插入
printf("please enter a seat:");
scanf("%d",&seat);
printf("please enter a value:");
scanf("%d",&value);
L_list=insert_by_seat(L_list,seat,value);
Output(L_list);
//任意元素查找
printf("please enter a seat:");
scanf("%d",&seat);
search_by_seat(L_list,seat);
Output(L_list);
//任意位置修改
printf("please enter a seat:");
scanf("%d",&seat);
printf("please enter a value:");
scanf("%d",&value);
modify_by_seat(L_list,seat,value);
Output(L_list);
//任意位置删除
printf("please enter a seat which you want to delete:");
scanf("%d",&seat);
L_list=delete_by_seat(L_list,seat);
Output(L_list);
//任意元素查找
printf("please enter the element you are looking for:");
scanf("%d",&value);
seat=search_by_element(L_list,value);
printf("the element you are looking for is in %d\n",seat);
//任意元素删除
printf("please enter the element you want to delete:");
scanf("%d",&value);
L_list=delete_by_element(L_list,value);
Output(L_list);
//任意元素插入
ElemType element;
printf("please enter the element you are looking for:");
scanf("%d",&value);
printf("please enter the element you want to insert:");
scanf("%d",&element);
L_list=insert_by_element(L_list,value,element);
Output(L_list);
//任意元素修改
printf("please enter the element you are looking for:");
scanf("%d",&value);
printf("please enter the element you want to modify:");
scanf("%d",&element);
modify_by_element(L_list,value,element);
Output(L_list);
//单链表逆置
L_list=rev_list(L_list);
Output(L_list);
//冒泡排序单链表
Bubble_list(L_list);
Output(L_list);
//简单选择排序单链表
simple_list(L_list);
Output(L_list);
return 0;
}