链接方式存储的线性表简称为链表。以“结点的序列”表示线性表称作单链表。用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)。链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息。
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据以结点表示的,每个结点的构成:元素 + 指针(指示其后元素的存储位置。
data域--存放结点值的数据域;
next域--存放结点的直接后继的地址(位置)的指针域。
带头节点单链表
函数实现
头文件
#pragma once
typedef struct Node
{
int data;//数据域
struct Node *next;//指向下一个节点
}Node,*List;
void InitList(List plist);
bool Insert_Head(List plist,int val);//头插
bool Insert_Tail(List plist,int val);//尾插
Node *Search(List plist,int key);
bool Delete(List plist,int key);
bool IsEmpty(List plist);
int GetLength(List plist);
void Show(List plist);
void Clear(List plist);
void Destroy(List plist);
void Revers(List plist);
基本操作的函数实现
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "list.h"
void InitList(List plist)//初始化单链表
{
assert(plist != NULL);
plist->next = NULL;
}
bool Insert_Head(List plist,int val)//头插
{
Node *p = (Node *)malloc(sizeof(Node));
p->data = val;
p->next = plist->next;
return true;
}
bool Insert_Tail(List plist,int val)//尾插
{
Node *p = (Node *)malloc(sizeof(Node));
p->data = val;
Node *q;
for(q=plist;q->next!=NULL;q=q->next);
p->next = q->next//将p插入在q的后面
q->next = p;
return true;
}
Node *Search(List plist,int key)//查找
{
Node *p;
for(p = plist->next;p!=NULL;p=p->next)
{
if(p->data == key)
{
return p;
}
}
return NULL;
}
bool Delete(List plist,int key)//删除
{
Node *p;
for(p=plist->next;p!=NULL;p=p->next)
{
if(p->next->data == key)
{
p->next = p->next->next;
p->data = p->next->data;
}
return true;
}
return false;
}
bool IsEmpty(List plist)//判空
{
if(plist->next==NULL)
{
return true;
}
return false;
}
int GetLength(List plist)
{
int num;
for(num=0;plist->next!=NULL;num++)
{
;
}
return num;
}
Show(List plist)//打印函数
{
for(Node *p=plist->next;p!=NULL;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
void Clear(List plist)//清空
{
Destroy(plist);
}
void Destroy(List plist)//摧毁
{
Node *p;
while(plist->next != NULL)
{
p = plist->next;
plist->next = p->next;
free(p);
}
/* 方法二
Node *p = plist->next;
//Node *q = p->next;//bug
Node *q;
while(p != NULL)
{
q = p->next;
free(p);
p = q;
}
plist->next = NULL;
*/
}
void Revers(List plist)
{
if(plist==NULL || plist->next==NULL || plist->next->next==NULL)
{
return ;
}
Node *p = plist->next;
Node *q;
plist->next = NULL;
while(p != NULL)
{
q = p->next;
p->next = plist->next;
plist->next = p;
p = q;
}
int mian()
{
Node plist;
InitList(&plist);
for (int i=0;i<5;i++)
{
Insert_Tail(&plist,i);
}
//Revers(&plist);
//Delete(&plist, 2);
Show(&plist);
return 0;
}
带尾节点的循环链表
代码实现
#include <stdio.h>
#include <stdlib.h>
void InitList(CList plist)
{
assert(plist != NULL);
if(plist == NULL)
{
return ;
}
plist->next = plist;
}
bool Insert_Head(CList plist,int val)
{
CNode *p = (CNode *)malloc(sizeof(CNode));
assert(p != NULL);
p->data = val;
p->next = plist->next;
plist->next = p;
return true;
}
void Show(CList plist)
{
for(CNode *p=plist->next;p!=plist;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}