一、单链表的定义和表示
线性表链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。因此,为了表示每个元素与其直接后继数据元素之间的逻辑关系,对数据元素来说,除了存储其本身的信息之外,还需要存储一个指示其直接后继的信息。这两部分信息组成数据元素的存储映像,称为结点。它包括两个域:
数据域:存储数据元素信息的域
指针域:存储直接后继存储位置的域
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 单链表任意位置修改
LinkList 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 L_list;
LinkList rear=L_list;
for(int i=1;i<seat;i++)
rear=rear->next;
rear->data=value;
return L_list;
}
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+1)
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;
}
四、多文件编辑实现单链表操作
头文件 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); //实现任意位置查找
LinkList modify_by_seat(LinkList L_list,int seat,ElemType value); //任意位置修改
LinkList delete_by_seat(LinkList L_list,int seat); //任意位置删除
#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);
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+1)
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;
}
LinkList 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 L_list;
LinkList rear=L_list;
for(int i=1;i<seat;i++)
rear=rear->next;
rear->data=value;
return L_list;
}
主函数 main.c
#include "head.h"
int main(int argc, const char *argv[])
{
LinkList L_list=NULL; //定义结点变量,注意定义时一定要指向NULL
int n; //定义循环输入次数
ElemType value; //定义数据域元素
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);
int seat;
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);
delete_by_seat(L_list,seat);
Output(L_list);
return 0;
}