不带头结点的单链表实现示例(C语言)
大部分代码为参考代码,在此基础上做了以下修改
代码较长,需耐心观看
其中 LinkList* 等价于 Lnode** 这俩个使用哪一个都可以,前提是在声明结构体的时候要加上。
修改的地方有:
在指定位置插入一个元素
删除指定位置的元素
打印链表更加合理
心得: 最重要的还是懂得原理 如何创建一个不带头结点的链表 如何实现增、删、改、查、打印等功能 重点还是原理。 不行就画图,慢慢理清逻辑,下一次不就会了嘛 加油!
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
typedef int DataType;
typedef struct LinkNode
{
DataType _data;
struct LinkNode *_pNext;
}Lnode, *LinkList;
void LinkListInit(LinkList* pHead);
Lnode* LinkListCreatNode(DataType data);
void LinkListDestoryNode(LinkList* pHead);
void LinkListPrint(LinkList* pHead);
void LinkListPushBack(LinkList* pHead, DataType data);
void LinkListPopBack(LinkList* pHead);
void LinkListPushFront(LinkList* pHead, DataType data);
void LinkListPopFront(LinkList* pHead);
int LinkListSize(LinkList* pHead);
void LinkListDestory(LinkList* pHead);
void LinkList_Insert_anysite(LinkList* pHead, DataType data, DataType pos);
void LinkList_del_anysite(LinkList* pHead, DataType pos);
int LinkListEmpty(LinkList* pHead);
void LinkListInit(LinkList* pHead)
{
assert(pHead);
*pHead = NULL;
}
Lnode* LinkListCreatNode(DataType data)
{
Lnode* pNewNode = (Lnode*)malloc(sizeof(Lnode));
assert(pNewNode);
pNewNode -> _data = data;
pNewNode -> _pNext = NULL;
return pNewNode;
}
void LinkListDestoryNode(LinkList* pHead)
{
free(pHead);
*pHead = NULL;
}
void LinkListPrint(LinkList* pHead)
{
Lnode* pCur = *pHead;
for(pCur; pCur != NULL; pCur = pCur -> _pNext)
{
if(pCur -> _pNext != NULL)
{
printf("%d----->", pCur -> _data);
}
else
{
printf("%d\n", pCur -> _data);
}
}
}
void LinkListPushBack(LinkList* pHead, DataType data)
{
Lnode* NewNode = LinkListCreatNode(data);
assert(pHead);
if(*pHead == NULL)
{
*pHead = NewNode;
return;
}
Lnode* pTail = *pHead;
while(pTail -> _pNext)
{
pTail = pTail -> _pNext;
}
pTail -> _pNext = NewNode;
}
void LinkListPopBack(LinkList* pHead)
{
assert(pHead);
if(*pHead == NULL)
{
printf("链表为空!,删除失败!\n");
return;
}
if((*pHead) -> _pNext == NULL)
{
free(pHead);
*pHead = NULL;
}
Lnode* pTail = *pHead;
Lnode* pPreTail = NULL;
while(pTail -> _pNext)
{
pPreTail = pTail;
pTail = pTail -> _pNext;
}
free(pTail);
pPreTail -> _pNext = NULL;
}
void LinkListPushFront(LinkList* pHead, DataType data)
{
assert(pHead);
Lnode* NewNode = LinkListCreatNode(data);
NewNode -> _pNext = (*pHead);
*pHead = NewNode;
}
void LinkListPopFront(LinkList* pHead)
{
Lnode* pDel = NULL;
assert(pHead);
if((*pHead) == NULL)
{
printf("链表为空!无法删除!\n");
return;
}
pDel = *pHead;
*pHead = pDel -> _pNext;
free(pDel);
}
int LinkListSize(LinkList* pHead)
{
assert(pHead);
Lnode* pSize = *pHead;
int count = 0;
while(pSize != NULL)
{
pSize = pSize -> _pNext;
count++;
}
return count;
}
void LinkListDestory(LinkList* pHead)
{
assert(pHead);
Lnode* pDpre = NULL;
Lnode* pD = *pHead;
while(pD)
{
pDpre = pD;
pD = pD -> _pNext;
free(pDpre);
}
*pHead = NULL;
}
void LinkList_Insert_anysite(LinkList* pHead, DataType data, DataType pos)
{
assert(pHead);
Lnode* pNewNode = LinkListCreatNode(data);
if(*pHead == NULL)
{
*pHead = pNewNode;
return;
}
if(pos == 1)
{
LinkListPushFront(pHead, data);
return;
}
if(pos > LinkListSize(pHead))
{
printf("插入位置有误!\n");
return;
}
Lnode* pCur = *pHead;
int i = 2;
while(pCur -> _pNext != NULL)
{
if(i == pos)
{
pNewNode -> _pNext = pCur -> _pNext;
pCur -> _pNext = pNewNode;
}
pCur = pCur -> _pNext;
i++;
}
return;
}
void LinkList_del_anysite(LinkList* pHead, DataType pos)
{
assert(pHead);
if ((*pHead) == NULL)
{
printf("链表为空!无法删除!\n");
return;
}
if (pos == 1)
{
LinkListPopFront(pHead);
return;
}
if(pos > LinkListSize(pHead))
{
printf("插入位置有误!\n");
return;
}
int i = 1;
Lnode* pE = *pHead;
while ( pE != NULL)
{
if (pE->_pNext != NULL)
{
i++;
if(i == pos)
{
Lnode* p = pE->_pNext;
pE -> _pNext = pE -> _pNext -> _pNext;
free(p);
}
return;
}
pE = pE->_pNext;
i++;
}
return;
}
int LinkListEmpty(Lnode** pHead)
{
assert(pHead);
return ((*pHead) == NULL);
}
void LinkListTest()
{
LinkList p;
LinkListInit(&p);
for(int i =1; i < 6; i++)
{
LinkListPushBack(&p, i);
}
LinkListPushBack(&p, 5);
LinkListPrint(&p);
LinkListPopBack(&p);
LinkListPrint(&p);
LinkListPushFront(&p, 5);
LinkListPushFront(&p, 6);
LinkListPrint(&p);
LinkListPopFront(&p);
LinkListPopFront(&p);
LinkListPrint(&p);
printf("链表长度为%d\n", LinkListSize(&p));
LinkList_Insert_anysite(&p,6,4);
LinkListPrint(&p);
LinkList_del_anysite(&p,2);
LinkListPrint(&p);
}
int main()
{
LinkListTest();
}
结果图:
|