typedef struct
{
int num;
char name[20];
int score;
}ElemType;
typedef struct LNode//声明结点的类型和指向结点的指针类型
{
ElemType data;//结点的数据域
struct LNode* next;//结点的指针域
}LNode, * LinkList;//LinkList 为指向结构体Lnode的指针类型
/*解释:定义了一个结构体类型 利用typedef重新起名字为Lnode 然后定义指针LinkList指向Lnode*/
/*定义结点指针p:Lnode *p; <==> LinkList P;*/
[ 算法2.6 ] 单链表的初始化(带头结点的单链表)
Status InitList(LinkList& L)
{
L = (LinkList)malloc(sizeof(LNode));
/*L=new LNode;*/
L->next = NULL;
return OK;
}
[ 补充算法 1 ] 判断链表是否为空
int ListEmpty(LinkList L)
{
if (L->next)//非空
{
return 0;
}
else
{
return 1;
}
}
[ 补充算法 2 ] 单链表的销毁
[ 算法思路 ]从头指针开始,依次释放所有结点;
Status DestroyList(LinkList& L)
{
LNode* p;//LinkList p;
while (L)
{
p = L;
L = L->next;
free(p);
}
return 0;
}
[ 补充算法 3 ] 清空链表(链表仍然存在,但链表中无元素,成为空链表)
[ 算法思路 ]依次释放所有结点,并将头结点的指针域设置为空;
Status ClearList(LinkList& L)
{
LNode* p, * q;
p = L->next;
while (p)
{
q = p->next;
free(p);
p = q;
}
L->next = NULL;//头结点的指针域为空
return OK;
}
[ 算法补充 4 ] 求单链表的表长
[ 算法思路 ]从首元结点开始,依次计数所有结点;
int ListLength(LinkList L)
{
int count = 0;//链表长度
LNode* p;
p = L->next;
while (p)
{
count++;
p = p->next;
}
return count;
}
[ 算法 2.7 ] 查找第 i 个元素
Status GetElem(LinkList L, int i, ElemType& e)
{
LNode* p;
int j = 1;
p = L->next;
while (p && j < i)
{
p = p->next;
j++;
}
if (!p || j > i)
{
return ERROR;
}
e = p->data;
return OK;
}
[ 算法 2.8 ] 按值查找
//O(n)
LNode* LocateElem(LinkList L, ElemType e)/*返回地址*/
{
LNode* p;
p = L->next;
while (p && p->data != e)
{
p = p->next;
}
return p;
}
int LocateElem(LinkList L, ElemType e)/*返回元素的下标*/
{
LNode* p;
int j = 1;
p = L->next;
while (p && p->data != e)
{
p = p->next;
j++;
}
if (p)
{
return j;
}
else
{
return 0;
}
}
[ 算法 2.9 ] 插入(在第 i 个结点前插入值为 e 的新结点)
Status ListInsert(LinkList& L, int i, ElemType e)
{
LNode *s, *p;
int j = 0;
s->data = e;
p = L;
while (p && j < i-1)//寻找i-1个结点 p指向i-1结点
{
p = p->next;
j++;
}
if (!p || j > i-1)
{
return ERROR;
}
s->next = p->next;
p->next = s;
return OK;
}
[ 算法 2.10 ] 删除(删除第 i 个结点)
Status ListDelete(LinkList& L, int i,ElemType &e)
{
LNode* p, * q;
int j = 0;
p = L;
while (p && j < i - 1)
{
p = p->next;
j++;
}
if (!p || j > i - 1)
{
return ERROR;
}
q = p->next;
p->next = q->next;//修改指针
e = q->data;
free(q);
return OK;
}
[ 算法 2.11 ] 建立单链表—头插法(元素插入在链表头部 )
/*倒位序插入n个元素的值*/
void CreateList(LinkList& L, int n)
{
LNode* p;
int i;
for (i = n; i > 0; i--)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d", &p->data);
p->next = L->next;
L->next = p;
}
}
[ 算法 2.12 ] 建立单链表–尾插法(元素插入在链表尾部)
/*正位序输入n个元素的值*/
void CreateList(LinkList& L, int n)
{
LNode* p, *r;
int i;
r = L;
for (i = n; i > 0; i--)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next = NULL;
r->next = p;
r = p;//尾指针指向新结点
}
}
循环链表:是一种 头尾相接的链表(即:表中最后一个结点的指针域指向头结点,整个链表形成一个环);
[ 算法 2.13 ] 循环链表的建立
void CreateList(LinkList& L, int n)
{
LNode* p, *r;
int i;
r = L;
for (i = n; i > 0; i--)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next = NULL;
r->next = p;
r = p;
}
r->next = L;
}
[ 算法 2.14 ] 带尾指针循环链表的合并
LinkList Connect(LinkList Ta, LinkList Tb)//假设Ta,Tb都是非空的单循环链表
{
LNode p;
p = (LinkList)malloc(sizeof(LNode));
p = Ta->next;
Ta->next = Tb->next->next;
free(Tb->next);
Tb->next = p;//修改指针
return Tb;
}
/*先看主函数了解 2021.1.17*/
#include
#include
#define ERROR 0
#define OK 1
typedef int Status;
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode* next;
}LNode, * LinkList;
Status InitList(LinkList& L)
{
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}
/*
void CreateList(LinkList& L, int n)
{
LNode* p;
for (int i = n; i > 0; i--)
{
p = (LNode *)malloc(sizeof(LNode));
scanf("%d", &p->data);
p->next = L->next;
L->next = p;
}
}
*/
void CreateList(LinkList& L, int n)
{
LNode* p, * r;
r = L;
for (int i = n; i > 0; i--)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d", &p->data);
p->next = NULL;
r->next = p;
r = p;
}
}
int ListLength(LinkList L)
{
int count = 0;//用于计数
LNode* p;
p = L->next;
while (p)
{
count++;
p = p->next;
}
return count;
}
Status GetElem(LinkList L, int i, ElemType& e)
{
int j = 1;
LNode* p;
p = L->next;
while (p && j < i)
{
p = p->next;
j++;
}
if (!p || j > i)
{
return ERROR;
}
e = p->data;
return OK;
}
int LocateElem(LinkList L, ElemType e)
{
LNode* p;
int j = 1;
p = L->next;
while (p && p->data != e)
{
p = p->next;
j++;
}
if (p)
{
return j;
}
else
{
return ERROR;
}
}
Status ListInsert(LinkList& L, int i, ElemType e)
{
LNode* s, * p;
s = (LinkList)malloc(sizeof(LNode));
int j = 0;
p = L;
s->data = e;
while(p && j < i - 1)
{
p = p->next;
j++;
}
if (!p || j > i - 1)
{
return ERROR;
}
s->next = p->next;
p->next = s;
return OK;
}
void print(LinkList L)
{
LNode* p;
p = L->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
Status ListDelete(LinkList& L, int i, ElemType& e)
{
LNode* p, * q;
p = L;
q = (LinkList)malloc(sizeof(LNode));
int j = 0;
while (p && j < i - 1)
{
p = p->next;
j++;
}
if (!p || j > i - 1)
{
return ERROR;
}
q = p->next;
e = q->data;
p->next = q->next;
free(q);
return OK;
}
void ListEmpty(LinkList L)
{
if (L->next)
{
printf("链表非空\n");
}
else
{
printf("链表为空\n");
}
}
Status ClearList(LinkList& L)
{
LNode* p, * q;
p = L->next;
while (p)
{
q = p->next;
free(p);
p = q;
}
L->next = NULL;
return OK;
}
Status DestroyList(LinkList& L)
{
LNode* p;
while (L)
{
p = L;
L = L->next;
free(p);
}
printf("销毁完毕\n");
return OK;
}
int main()
{
int n;
int i;
LinkList L;
ElemType e;
InitList(L);/*带头结点的链表初始化*/
printf("输入元素的个数:");
scanf("%d", &n);//要输入的元素个数
printf("输入元素:");
//CreateList(L, n);/*头插法输入元素-倒叙状态*/
CreateList(L, n);/*尾插法输入元素-顺序*/
printf("单链表的长度:%d\n", ListLength(L));/*求单链表的表长*/
printf("输入查找的i位置:");
scanf("%d", &i);
GetElem(L, i, e);/*查找第i个元素*/
printf("查找的第i个元素是:%d\n", e);
printf("输入要查找得值:");
scanf("%d", &e);
printf("查找到的元素的下标为:%d\n", LocateElem(L, e));/*按值查找*/
printf("插入的位置:");
scanf("%d",&i);
printf("要插入的元素:");
scanf("%d", &e);
ListInsert(L, i, e);/*第i个位置之前插入元素e*/
printf("插入元素后的链表:");
print(L);//输出链表
printf("输入删除元素的位置:");
scanf("%d", &i);
ListDelete(L, i, e);/*删除第i个元素*/
printf("删除的元素%d\n",e);
printf("删除元素后的链表:");
print(L);
ListEmpty(L);/*判断链表是否为空*/
ClearList(L);/*清空单链表*/
printf("清空单链表后:");
ListEmpty(L);/*判断链表是否为空*/
DestroyList(L);/*销毁单链表*/
return 0;
}