#include <stdio.h>
#include <stdlib.h>
//结点结构体
struct Node
{
int a;
struct Node * pNext;
};
//链表头尾指针
struct Node * g_pEnd = NULL;//这里的null没有意义,因为在主函数开始会直接给head和end申请地址,成为空头
struct Node * g_pHead = NULL;
void InitListHead();
struct Node * CreatNode(int a);
void AddListTail(int a);
void AddListHead(int a);
void ScanList();
int main()
{
InitListHead();
//操作
//在这里不能头添加删尾,原因不清楚
//以后熟练之前暂时都使用有空头尾添加
AddListTail(10);
AddListTail(20);
AddListTail(30);
AddListTail(40);
DeleteListRand(20);
ScanList();
system("Pause");
}
//空头链表初始化
void InitListHead()
{
//链表空头
g_pHead = (struct Node *)malloc(sizeof(struct Node)); //此时head是有地址的,成为空头
g_pHead->pNext = NULL;
g_pEnd = g_pHead;//刚开始的时候,end地址就是head地址,表示一个空头结点
}
//链表首节点的创建
struct Node * CreatNode(int a)
{
//创建一个结点
struct Node *pTemp = (struct Node *)malloc(sizeof(struct Node));
//结点成员赋值
pTemp->a = a;
pTemp->pNext = NULL;
return pTemp;
}
//尾添加
void AddListTail(int a)
{
struct Node *pTemp = CreatNode(a);
//链接
g_pEnd->pNext = pTemp;
g_pEnd = pTemp;
}
//头添加
void AddListHead(int a)
{
struct Node *pTemp = CreatNode(a);
//链接
pTemp->pNext = g_pHead->pNext;
g_pHead->pNext = pTemp;
}
//遍历整个链表
void ScanList()
{
struct Node *pTemp = g_pHead->pNext; //由于第一个是空头g_pHead,所以遍历的时候直接从g_pHead指向的下一个结点开始遍历
while (pTemp)
{
printf("%d\n",pTemp->a);
pTemp = pTemp->pNext;
}
}
//查找指定结点,并且返回结点地址
struct Node * SelectNode(int index)
{
struct Node *pTemp = g_pHead->pNext; //由于第一个是空头g_pHead,所以遍历的时候直接从g_pHead指向的下一个结点开始遍历
while (pTemp)
{
if (index == pTemp->a)
{
return pTemp;
}
pTemp = pTemp->pNext;
}
return NULL;
}
//任意位置添加结点(根据链表中的某个值,在后面添加)
void AddListRank(int index, int a)
{
//判断链表有没有东西
if (NULL == g_pHead->pNext)
{
printf("链表无节点");
}
//找index结点
struct Node *pTemp = SelectNode(index);
if (NULL == pTemp)
{
printf("查无此结点\n");
}
//找到了,连接到指定位置
struct Node * pNode = CreatNode(a);
if (pNode == g_pEnd)
{
g_pEnd->pNext = pNode;
g_pEnd = pNode;
}
else
{
pNode->pNext = pTemp->pNext;
pTemp->pNext = pNode;
}
}
//struct Node * Find(int index)
//{
// int cnt = 0;
// //判断链表有没有东西
// if (NULL == g_pHead->pNext)
// {
// printf("链表无节点");
// }
// //找index结点
// struct Node *pTemp = g_pHead;
// while(pTemp)
// {
// pTemp = pTemp->pNext;
// if (cnt == index)
// {
// return pTemp;
// }
// cnt++;
// }
//}
//
//void AddListNum(int a, int index)
//{
// struct Node * pNode = CreatNode(a);
// struct Node * pTemp = Find(index);
// if (pTemp == g_pEnd)
// {
// g_pEnd->pNext = pNode;
// g_pEnd = pNode;
// }
// else
// {
// pNode->pNext = pTemp->pNext;
// pTemp->pNext = pNode;
// }
//}
//删头
void DeleteListHead()
{
//判断链表有没有东西
if (NULL == g_pHead->pNext)
{
printf("链表无头");
return;
}
struct Node * pTemp = g_pHead->pNext;
//变头
g_pHead->pNext = g_pHead->pNext->pNext;
//释放
free(pTemp);
}
//删尾
void DeleteListTail()
{
//判断链表有没有东西
if (g_pHead->pNext == NULL)
{
printf("链表无尾");
return;
}
//有一个结点
if (g_pHead->pNext == g_pEnd)
{
free(g_pEnd);
g_pHead->pNext = NULL;
g_pEnd = g_pHead;
}
else
{
//找到尾结点的下一个
struct Node *pTemp = g_pHead->pNext; //由于第一个是空头g_pHead,所以遍历的时候直接从g_pHead指向的下一个结点开始遍历
while (pTemp)
{
if (g_pEnd == pTemp->pNext)
{
break;
}
pTemp = pTemp->pNext;
}
//pTemp是尾巴的前一个
free(g_pEnd);
//变新尾巴
g_pEnd = pTemp;
//尾巴下一个赋值空
g_pEnd->pNext = NULL;
}
}
//删指定结点
void DeleteListRand(int a)
{
//判断链表有没有东西
if (NULL == g_pHead->pNext)
{
printf("链表无节点");
}
//找index结点
struct Node *pTemp = SelectNode(a);
if (NULL == pTemp)
{
printf("查无此结点\n");
}
//找到结点
//头,尾和中间
//找到前一个结点
//只有一个结点
if (pTemp == g_pEnd)
{
DeleteListTail();
}
else
{
struct Node *pT = g_pHead;
while (pT)
{
if(pTemp == pT->pNext)
{
break;
}
pT = pT->pNext;
}
//删除
pT->pNext = pTemp->pNext;
//释放
free(pTemp);
}
}
//释放链表
void FreeList()
{
struct Node * pTemp = g_pHead;
while (pTemp != NULL)
{
struct Node *pT = pTemp;
pTemp = pTemp->pNext;
free(pT);
}
g_pHead = NULL;
g_pEnd = NULL;
}