单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据
在写单链表的时候,需要对结构体有一定的了解(这里就不做过多的结构体介绍)
头结点一般在栈区或者数据区开辟且头结点不存储有效数据,头结点的数据域存储当前结点的的个数,除头结点外,其他结点在堆区开辟空间
一、创建带头结点的单链表
带头结点的单链表通过结构体和联合体一起创建
#define FALSE 0
#define TRUE 1
typedef int ElemType;
typedef union DataType
{
ElemType value;
int num;
}DataType;
typedef struct LNode
{
DataType data; // 数据元素或者个数
struct LNode *next; // 存储下一个数据结点的地址
}LNode, *LinkList;
static LinkList ApplyNode(ElemType val, LinkList next) //创建结点并赋值
{
LinkList p = (LinkList)malloc(sizeof(LNode));
if(p == NULL) return NULL;
p->data.value = val;
p->next = next;
return p;
}
二、单链表所实现的功能(带头结点的单链表)
1.找单链表前一个位置
static LinkList FindPrior_Pos(LinkList head, int pos) //找前一个位置
{
LinkList p = head;
while(pos>0)
{
p = p->next;
pos--;
}
return p;
}
2.单链表创建结点并赋值
static LinkList ApplyNode(ElemType val, LinkList next) //创建结点并赋值
{
LinkList p = (LinkList)malloc(sizeof(LNode));
if(p == NULL) return NULL;
p->data.value = val;
p->next = next;
return p;
}
3.单链表初始化
void Init_LinkList(LinkList head) //初始化
{
assert(head!=NULL);
if(head==NULL) exit(0);
head->next = NULL;
head->data.num = 0;
}
4.插入
(1)位置插
int Insert_LinkList_Pos(LinkList head, ElemType val, int pos) //位置插
{
if(head == NULL) exit(0);
if(pos<0||pos>head->data.num) return FALSE;
LinkList p = FindPrior_Pos(head,pos);
LinkList q = ApplyNode(val,p->next);
if(q == NULL) return FALSE;
p->next = q;
head->data.num++;
return TRUE;
}
(2)头插
int Insert_LinkList_Head(LinkList head, ElemType val) //头插
{
if(head == NULL) exit(0);
LinkList p = FindPrior_Pos(head,0);
LinkList q = ApplyNode(val,p->next);
if(q == NULL) return FALSE;
p->next = q;
head->data.num++;
return TRUE;
}
(3)尾插
int Insert_LinkList_Tail(LinkList head, ElemType val) //尾插
{
if(head == NULL) exit(0);
LinkList p = FindPrior_Pos(head,head->data.num);
LinkList q = ApplyNode(val,p->next);
if(q == NULL) return FALSE;
p->next = q;
head->data.num++;
return TRUE;
}
5.删除
(1)位置删
int Delete_LinkList_Pos(LinkList head, int pos) //位置删
{
if(head == NULL) exit(0);
if(pos<-1||pos>=head->data.num) return FALSE;
LinkList p = FindPrior_Pos(head,pos);
LinkList q = p->next;
p->next = q->next;
free(q);
head->data.num--;
return TRUE;
}
(2)头删
int Delete_LinkList_Head(LinkList head) //头删
{
if(head == NULL) exit(0);
LinkList p = FindPrior_Pos(head,0);
LinkList q = p->next;
p->next = q->next;
free(q);
head->data.num--;
return TRUE;
}
(3)尾删
int Delete_LinkList_Tail(LinkList head) //尾删
{
if(head == NULL) exit(0);
LinkList p = FindPrior_Pos(head,head->data.num-1);
LinkList q = p->next;
p->next = q->next;
free(q);
head->data.num--;
return NULL;
}
6.打印
void Show_LinkList(LinkList head) //打印
{
if(head == NULL) exit(0);
LinkList p = head->next;
for(int i = 0;i<head->data.num;i++)
{
printf("%d ",p->data.value);
p = p->next;
}
printf("\n");
}
7.清空单链表
int Clear_LinkList(LinkList head) //清空
{
if(head == NULL) exit(0);
while(head->data.num)
{
Delete_LinkList_Tail(head);
}
return TRUE;
}
8.销毁单链表
int Destroy_LinkList(LinkList head) //销毁
{
return Clear_LinkList(head);
}
#include
#include
#include
#define FALSE 0
#define TRUE 1
typedef int ElemType;
typedef union DataType
{
ElemType value;
int num;
}DataType;
typedef struct LNode
{
DataType data; // 数据元素或者个数
struct LNode *next; // 存储下一个数据结点的地址
}LNode, *LinkList;
static LinkList ApplyNode(ElemType val, LinkList next) //创建结点并赋值
{
LinkList p = (LinkList)malloc(sizeof(LNode));
if(p == NULL) return NULL;
p->data.value = val;
p->next = next;
return p;
}
static LinkList FindPrior_Pos(LinkList head, int pos) //找前一个位置
{
LinkList p = head;
while(pos>0)
{
p = p->next;
pos--;
}
return p;
}
void Init_LinkList(LinkList head) //初始化
{
assert(head!=NULL);
if(head==NULL) exit(0);
head->next = NULL;
head->data.num = 0;
}
int Insert_LinkList_Pos(LinkList head, ElemType val, int pos) //位置插
{
if(head == NULL) exit(0);
if(pos<0||pos>head->data.num) return FALSE;
LinkList p = FindPrior_Pos(head,pos);
LinkList q = ApplyNode(val,p->next);
if(q == NULL) return FALSE;
p->next = q;
head->data.num++;
return TRUE;
}
int Insert_LinkList_Head(LinkList head, ElemType val) //头插
{
if(head == NULL) exit(0);
LinkList p = FindPrior_Pos(head,0);
LinkList q = ApplyNode(val,p->next);
if(q == NULL) return FALSE;
p->next = q;
head->data.num++;
return TRUE;
}
int Insert_LinkList_Tail(LinkList head, ElemType val) //尾插
{
if(head == NULL) exit(0);
LinkList p = FindPrior_Pos(head,head->data.num);
LinkList q = ApplyNode(val,p->next);
if(q == NULL) return FALSE;
p->next = q;
head->data.num++;
return TRUE;
}
int Delete_LinkList_Pos(LinkList head, int pos) //位置删
{
if(head == NULL) exit(0);
if(pos<-1||pos>=head->data.num) return FALSE;
LinkList p = FindPrior_Pos(head,pos);
LinkList q = p->next;
p->next = q->next;
free(q);
head->data.num--;
return TRUE;
}
int Delete_LinkList_Head(LinkList head) //头删
{
if(head == NULL) exit(0);
LinkList p = FindPrior_Pos(head,0);
LinkList q = p->next;
p->next = q->next;
free(q);
head->data.num--;
return TRUE;
}
int Delete_LinkList_Tail(LinkList head) //尾删
{
if(head == NULL) exit(0);
LinkList p = FindPrior_Pos(head,head->data.num-1);
LinkList q = p->next;
p->next = q->next;
free(q);
head->data.num--;
return NULL;
}
int Clear_LinkList(LinkList head) //清空
{
if(head == NULL) exit(0);
while(head->data.num)
{
Delete_LinkList_Tail(head);
}
return TRUE;
}
int Destroy_LinkList(LinkList head) //销毁
{
return Clear_LinkList(head);
}
LinkList FindNode_Pos(LinkList head, int pos) //查找
{
if(head == NULL) exit(0);
if(pos<0||pos>head->data.num) return NULL;
LinkList p = FindPrior_Pos(head,pos);
return p->next;
}
void Show_LinkList(LinkList head) //打印
{
if(head == NULL) exit(0);
LinkList p = head->next;
for(int i = 0;i<head->data.num;i++)
{
printf("%d ",p->data.value);
p = p->next;
}
printf("\n");
}
int List(LinkList head,int k) //删除倒数第k个
{
if(head == NULL)
{
return FALSE;
}
LinkList p = head;
LinkList q = head;
for(int i=1;i<k;i++)
{
q = q->next;
}
while(q->next != NULL)
{
q = q->next;
p = p->next;
}
return p->data.value;
}
int main()
{
//以下为测试内容----------------------
LNode head;
Init_LinkList(&head);
for(int i = 0;i<10;i++)
{
Insert_LinkList_Tail(&head,i);
}
Show_LinkList(&head);
Insert_LinkList_Head(&head,100);
Insert_LinkList_Pos(&head,200,head.data.num);
Show_LinkList(&head);
Delete_LinkList_Head(&head);
Delete_LinkList_Tail(&head);
Delete_LinkList_Pos(&head,head.data.num-1);
Show_LinkList(&head);
printf("%d\n",*(FindNode_Pos(&head,5)));
Clear_LinkList(&head);
Show_LinkList(&head);
return 0;
}