链表:逻辑上是连续的,再物理空间上不是连续的(每个数据存储的空间都是单独申请的)
结点结构:数据元素+指针域
单链表:只有一个指针域,存储下一个结点的地址
1、带头节点的单链表:
第一个结点不存储数据元素,只是利用其指针域来存储整个链表的起始(将头节点直接定义在栈区且头节点在正式操作链表之前就已经存在,其余结点定义在堆区)
结构:
typedef int ElemType;
typedef union DataType
{
ElemType value;
int num;
}DataType;
typedef struct LNode
{
DataType data;//数据元素
struct LNode *next;//存储下一个数据节点的地址
}LNode,*LinkList;
初始化:
void Init_LinkList(LinkList head)
{
assert(head != NULL);
if(head == NULL) exit(0);
head->next = NULL;
head->data.num = 0;
}
功能实现:插入(头插、按位插入、尾插),删除(头删、尾删、按位删除),打印,销毁
//申请一个结点
static LinkList ApplyNode(ElemType val,LinkList next)
{
LinkList new_node = (LinkList)malloc(sizeof(LNode));
if(new_node == NULL)
return NULL;
new_node->next = next;
new_node->data.value = val;
return new_node;
}
//查找目标位置的前一个位置
static LinkList FindPrior(LinkList head,int pos)
{
LinkList p = head;
while(pos > 0)
{
p = p->next;
pos--;
}
return p;
}
//插入(按位插入)
int Insert_LinkList_Pos(LinkList head,ElemType val,int pos)
{
assert(head != NULL);
if(head == NULL) exit(0);
if(pos < 0 || pos > head->data.num)
return false;
LinkList p = FindPrior_Pos(head,pos);
LinkList new_node = ApplyNode(val,p->next);
if(new_node == NULL)
return false;
p->next = new_node;
head->data.num++;
return true;
}
//头插
int Insert_LinkList_Head(LinkList head,ElemType val)
{
return Insert_LinkList_Pos(head,val,0);
}
//尾插
int Insert_LinkList_Tail(LinkList head,ElemType val)
{
assert(head != NULL);
if(head == NULL ) exit(0);
return Insert_LinkList_Pos(head,val,head->data.num);
}
//删除结点(按位删)
int Delete_LinkList_Pos(LinkList head,int pos)
{
assert(head != NULL);
if(head == NULL) exit(0);
if(pos < 0 || pos >= head->data.num)
return false;
LinkList p = FindPrior(head,pos);
LinkList q = p->next;
p->next = q->next;
free(q);
head->data.num--;
return true;
}
//头删
int Delete_LinkList_Head(LinkList head)
{
return Delete_LinkList_Pos(head,0);
}
//尾删
int Delete_LinkList_Tail(LinkList head)
{
assert(head != NULL);
if(head == NULL) exit(0);
return Delete_LinkList_Pos(head,head->data.num-1);
}
//打印
void Show(LinkList head)
{
assert(head != NULL);
if(head == NULL) exit(0);
LinkList p = head->next;
while(p)
{
printf("%d ",p->data.value);
p = p->next;
}
peintf("\n");
}
//清除
int Clear_LinkList(LinkList head)
{
while(head->data.num)
{
if(!Delete_LinkList_Head(head))
return false;
}
return true;
}
//销毁
int Destory_LinkList(LinkList head)
{
return Clear_LinkList(head);
}
2、不带头节点的单链表
定义链表时定义的是一个头指针,这个指针将来指向第一个数据结点
结构:
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
初始化:
void Init_LinkList(LinkList *head)
{
assert(head != NULL);
if(head == NULL) exit(0);
*head->next = NULL;
}
功能:插入(头插、尾插、按位插入),删除(头删、尾删、按位删除),打印
//寻找目标位置的前一个结点的位置
static int FindPrior(LinkList head,int pos)
{
LinkList p = head;
while(pos - 1)
{
p = p->next;
pos--;
}
return p;
}
//申请新结点
static int ApplyNode(ElemType val,LinkList *next)
{
LinkList new_node = (LinkList)malloc(sizeof(LNode));
if(new_node == NULL)
return false;
new_node->data = val;
new_node->next = next;
return new_node;
}
//获取LinkList的长度
static int GetLinkListLength(LinkList *head)
{
LinkList p = head;
int length = 0;
while(p != NULL)
{
length++;
p = p->next;
}
return length;
}
//头插
int Insert_LinkList_Head(LinkList *head,ElemType val)
{
assert(head != NULL);
if(head == NULL) exit(0);
LinkList p = ApplyNode(val,*head);
*head = p;
return true;
}
//按位插入数据
int Insert_LinkList_Pos(LinkList *head,ElemType val,int pos)
{
assert(head != NULL);
if(head == NULL) exit(0);
if(pos < 0 || pos > GetLinkListLength(head))
return false;
if(pos == 0)
return Insert_LinkList_Head(head,val);
LinkList p = FindPrior(*head,pos);//找到目标位置的前一个位置,在其后插入新结点
LinkList q = ApplyNode(val,p->next);//申请新结点
p->next = q;
return true;
}
//尾插
int Insert_LinkList_Tail(LinkList *head,ElemType val)
{
assert(head != NULL);
if(head == NULL) exit(0);
return Insert_LinkList_Pos(head,val,GetLinkListLength(head));
}
//头删
int Delete_LinkList_Head(LinkList *head)
{
assert(head != NULL);
if(head == NULL || *head == NULL) exit(0);//*head指链表是否为空
LinkList p = *head;
*head = p->next;
free(p);
return true;
}
//按位删除
int Delete_LinkList_Pos(LinkList *head,int pos)
{
assert(head != NULL);
if(head == NULL) exit(0);
if(pos < 0 || pos >= GetLinkListLength(head))
return false;
if(pos == 0)
return Delete_LinkList_Head(head);
LinkList p = FindPrior(*head,pos);
LinkList q = p->next;
p->next = q->next;
free(q);
return true;
}
//尾删
int Delete_LinkList_Tail(LinkList *head)
{
assert(head != NULL);
if(head == NULL) exit(0);
return Delete_LinkList_Pos(head,GetLinkListLength(head)-1);
}
//打印
void Show_LinkList(LinkList head)
{
assert(head != NULL);
if(head == NULL) exit(0);
LinkList p = head;
while(p != NULL)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}