单链表:
1、逻辑上连续,位置上可以不连续的存储方式。
2、单链表由无数个结点组成,每个结点由数据段和指针域组成,数据段存储数据,指针域存储后继的地址。
3、每个结点最多有一个前继和一个后继。
4、其中第一个结点没有前继,所以我们通常建立一个头结点来保存他的位置,其中头结点的数据不关注。
5、最后一个结点没有后继,所以我们将最后一个结点的指针域赋为NULL。
单链表基本操作的函数实现:
typedef int DataType;
#define NULL 0
#include <assert.h>
#include<malloc.h>
typedef struct Node//创建结点类型
{
DataType _data;
struct Node* _pNext;
}*PNode;
void InitList(PNode* pHead)//初始化单链表
{
assert(pHead);
*pHead = NULL;
}
PNode BuyNode(DataType data)//新建结点
{
PNode pNewNode = (PNode)malloc(sizeof(struct Node));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
// 打印链表
void PrintList(PNode pHead)
{
PNode pCur = pHead;
while (pCur)
{
printf("%d--->", pCur->_data);
pCur = pCur->_pNext;
}
printf("NULL\n");
}
// 尾插法
void PushBack(PNode* pHead, DataType data)
{
assert(pHead);
if (NULL == *pHead)
{
*pHead = BuyNode(data);
}
else
{
PNode pTailNode = *pHead;
while (pTailNode->_pNext)
{
pTailNode = pTailNode->_pNext;
}
pTailNode->_pNext = BuyNode(data);
}
}
// 尾删法
//1.空--->返回
//2.只有一个节点--->删除,pHead->NULL
//3.多个节点--->删除最后节点
void PopBack(PNode* pHead)
{
assert(pHead);
if (NULL == *pHead)
{
return;
}
else if (NULL == (*pHead)->_pNext)
{
free(*pHead);
*pHead = NULL;
}
else
{
//找到最后一个节点
PNode pTailNode = *pHead;
PNode pPre = NULL;
while (pTailNode->_pNext)
{
pPre = pTailNode;
pTailNode = pTailNode->_pNext;
}
pPre->_pNext = NULL;
free(pTailNode);
}
}
// 头插法
void PushFront(PNode* pHead, DataType data)
{
PNode pNewNode;
assert(pHead);
pNewNode = BuyNode(data);
if (NULL == pNewNode)
{
return;
}
pNewNode->_pNext = *pHead;
*pHead = pNewNode;
}
// 头删法
void PopFront(PNode* pHead)
{
PNode pDel = *pHead;
assert(pHead);
if (NULL == *pHead)
{
return;
}
else
{
*pHead = (*pHead)->_pNext;
free(pDel);
}
}
// 返回结点在链表中的位置
PNode Find(PNode pHead, DataType data)
{
PNode pCur = pHead;
while (pCur)
{
if (pCur->_data == data)
return pCur;
pCur = pCur->_pNext;
}
return NULL;
}
// 任意位置插入值为data的结点
void Insert(PNode pos, DataType data)
{
PNode pNewNode = BuyNode(data);
if (NULL == pos)
return ;
pNewNode = BuyNode(data);
if (NULL == pNewNode)
return ;
pNewNode->_pNext = pos->_pNext;
pos->_pNext = pNewNode;
}
// 删除pos位置上的结点
void Erase(PNode* pHead, PNode pos)
{
PNode pCur = NULL;
PNode pDel = NULL;
assert(pHead);
if (NULL == (*pHead) || NULL == pos)
return;
pCur = *pHead;
pDel = pCur->_pNext;
if ((*pHead) == pos)
PopFront(pHead);
else
{
while ((pos != pDel) && pos)
{
pCur = pCur->_pNext;
pDel = pDel->_pNext;
}
pCur->_pNext = pDel->_pNext;
free(pDel);
}
}
// 求链表中节点的个数
size_t Size(PNode pHead)
{
int ret = 0;
PNode pCur = NULL;
if (NULL == pHead)
return;
pCur = pHead;
while (pCur)
{
pCur = pCur->_pNext;
ret++;
}
return ret;
}
// 销毁单链表
void DestroyList(PNode* pHead)
{
PNode pCur = *pHead;
PNode pNext = NULL;
while (pCur)
{
pNext = pCur->_pNext;
free(pCur);
pCur = pNext;
}
*pHead = NULL;
}
测试函数
void Testlist()
{
PNode pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PushBack(&pHead, 6);
PushBack(&pHead, 7);
PushBack(&pHead, 8);
PopBack(&pHead);
PushFront(&pHead, 0);
PopFront(&pHead);
Insert(Find(pHead, 3), 4);
PrintList(pHead);
}