/*
链式表示的线性表
定义:采用一组任意储存单元存放线性表的元素,这组存储单元可以是
连续的,也可以是不连续的。
1.单链表
2.循环单链表
3.双向链表
以单链表为基础,单链表的每一个节点有一个数据域和一个指针域,指
针域存放的是下一个节点的地址,而尾节点的指针域为NULL,他有一个
头结点,头结点没有数据,只用于存放链表首节点(第一个节点)的地
址,即确定一个单链表,只需要一个信息,积极头节点的地址。

循环单链表是一种首位相连的单链表,将单链表尾节点的指针域由空指
针改为指向头结点或者第一个节点,整个链表就形成一个环。

双向链表就是链表中每个节点有两个指针域,一个指向前驱节点,另一
个指向直接后继节点。
双向链表 和 循环链表 结合就形成了双向循环链表。
*/

# include <stdio.h>
# include <stdlib.h>
# include <malloc.h>

// 单向链表
typedef struct list
{
int data; // 链表数据域
struct list * pNext;
}Node, * pNode;

// 链表的创建
pNode Create_List();
// 链表的遍历
void Travel_List(pNode);
// 判断链表是否为空
bool Is_Empty(pNode);
// 计算链表长度
int Length_List(pNode);
// 链表节点的插入, 形参为链表头地址 在哪个位置前插入 插入的节点的值
void Insert_List(pNode, int, int);
// 链表节点的删除,形参为链表头地址,需要删除的节点的位置
void Delete_List(pNode, int);
// 链表的排序
void Seq_List(pNode);
// 链表的销毁
void Destroy_List(pNode);

int main(void)
{
pNode pHead = Create_List();
Travel_List(pHead);

int pos, val;
printf("请输入需要插入的位置及该的数据!\n");
scanf("%d %d", &pos, &val);
Insert_List(pHead, pos, val);
Travel_List(pHead);

printf("请输入需要删除的位置!\n");
scanf("%d %d", &pos);
Delete_List(pHead, pos);
Travel_List(pHead);

Destroy_List(pHead);

return 0;
}

pNode Create_List(void)
{
int len;
printf("请输入您需要的链表长度:");
scanf("%d", &len);
pNode pHead = (pNode)malloc(sizeof(Node));
if (NULL == pHead)
{
printf("动态内存分配失败!\n");
exit(-1);
}
pHead->pNext = NULL;
pNode pNew, pTemp;
pNew = pHead;
for (int i = 0; i < len; ++i)
{
pTemp = (pNode)malloc(sizeof(Node));
if (NULL == pTemp)
{
printf("动态内存分配失败!\n");
exit(-1);
}
pTemp->pNext = NULL;
pNew->pNext = pTemp;
printf("请输入此节点储存的数据:");
scanf("%d", &pTemp->data);
printf("\n");
pNew = pNew->pNext;
}

return pHead;
}

void Travel_List(pNode pHead)
{
pNode pTemp;
while (pHead->pNext != NULL)
{
pTemp = pHead->pNext;
printf("%-5d\n", pTemp->data);
pHead = pHead->pNext;
}

return;
}

bool Is_Empty(pNode pHead)
{
if (NULL == pHead->pNext)
return true;
else
return false;
}

int Length_List(pNode pHead)
{
int cnt = 0; // 记录链表长度
while (NULL != pHead->pNext)
{
++cnt;
pHead = pHead->pNext;
}

return cnt;
}

void Insert_List(pNode pHead, int pos, int val)
{
// 首先要判定被插入的位置是否存在
pNode pTemp = pHead;
int i = 0;
// 说明:此循环结束后pTemp记录的是第pos-1个节点的地址
while (NULL != pTemp && i < pos-1)
{
pTemp = pTemp->pNext;
++i;
}
if (NULL == pTemp || i > pos-1)
{
printf("插入失败!\n");
exit(-1);
}
pNode pNew;
pNew = (pNode)malloc(sizeof(Node));
if (NULL == pNew)
{
printf("动态内存分配失败!\n");
exit(-1);
}
pNew->data = val;
pNew->pNext = pTemp->pNext;
pTemp->pNext = pNew;

return;
}

void Delete_List(pNode pHead, int pos)
{
pNode pTemp = pHead;
int i = 0;
while (NULL != pTemp && i < pos-1)
{
pTemp = pTemp->pNext;
++i;
}
if (NULL == pTemp || i > pos-1)
{
printf("删除失败!\n");
exit(-1);
}
pNode pTemp1 = pTemp->pNext;
int val = pTemp1->data;
pTemp->pNext = pTemp1->pNext;
printf("被删除的节点数据为:%d\n", val);

return;
}

void Seq_List(pNode pHead)
{
pNode pTemp, pTemp1, pTemp2, pTemp3, pMax, pMax1, pMax2;
pTemp = pHead; // 表示要开始用来比较的原节点的前一个节点地址
pTemp1 = pTemp->pNext; // 表示开始用来比较的原节点的地址
while (NULL != pTemp1->pNext)
{
pMax1 = pTemp; // 追踪最大值前面的节点
pMax = pTemp1; // 用来追踪最大值的节点
pTemp2 = pMax; // 用于追踪被比较点前一个点的地址
pTemp3 = pMax->pNext; // 用于追踪被比较点
while (NULL != pTemp2->pNext)
{
if (pMax->amount < pTemp3->amount)
{
pMax1 = pTemp2;
pMax = pTemp3;
}
pTemp2 = pTemp2->pNext;
if (NULL != pTemp2->pNext)
pTemp3 = pTemp2->pNext;
}
pMax1->pNext = pMax->pNext;
pMax->pNext = pTemp1;
pTemp->pNext = pMax;
pTemp = pMax;
pTemp1 = pTemp->pNext;
}

return;
}

void Destroy_List(pNode pHead)
{
pNode pTemp;
while (pHead != NULL)
{
pTemp = pHead->pNext;
free(pHead);
pHead = pTemp;
}

return;
}

 

 

转载请注明出处