带头结点的单链表(无循坏)
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <assert.h>
#include <malloc.h>
#pragma warning <disable:4996>
//////////////////////////////////////////////////////
typedef int DataType;
typedef struct SListNode
{
DataType _data;
struct SListNode* _pNext;
}Node, *PNode;
void SListInit(PNode* ppHead);//初始化//二级指针
PNode TouchSListNode(DataType data);//创建节点
void SListPrint(PNode pHead);//打印链表
void PrintSListFromTail(PNode pHead); //递归逆序打印链表
void SListPushFront(PNode* ppHead, DataType data); //头插
void SListPopFront(PNode* ppHead);//头删
void SListPushBack(PNode* ppHead, DataType data);//尾插
void SListPopBack(PNode* ppHead);//尾删
void SListInsert(PNode *ppHead, PNode pos, DataType data);//任意位置插入//将data插入pos之前的位置
void SListErase(PNode *ppHead, PNode pos);//任意位置的删除
PNode FindPos(PNode pHead, DataType data);//找到第一个值为data的节点
//////////////////////////////////////////////////////
void SListInit(PNode* ppHead)//初始化//二级指针
{
assert(ppHead);
*ppHead = NULL;
}
void SListPrint(PNode pHead)//打印链表
{
PNode pCur = pHead;
while (pCur)
{
printf("%d --> ", pCur->_data);
pCur = pCur->_pNext;
}
printf("NULL\n");
}
//时间复杂度 O(n) 空间复杂度 O(n)
void PrintSListFromTail(PNode pHead) //递归逆序打印链表
{
if (pHead)//递归出口
{
PrintSListFromTail(pHead->_pNext);
printf(" <-- %d", pHead->_data);
}
}
PNode TouchSListNode(DataType data)//创建节点
{
PNode pNewNode = (PNode)malloc(sizeof(Node));
assert(pNewNode);
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
void SListPushFront(PNode* ppHead, DataType data) //头插
{
PNode pNewNode = TouchSListNode(data);
pNewNode->_pNext = *ppHead;
*ppHead = pNewNode;
}
void SListPopFront(PNode* ppHead)//头删
{
assert(ppHead);
PNode pNewNode = *ppHead;
if (NULL == *ppHead)
return;
*ppHead = pNewNode->_pNext;
free(pNewNode);
}
void SListPushBack(PNode* ppHead, DataType data)//尾插
{
assert(ppHead);//是否存在
if (NULL == *ppHead)//空链表
{
*ppHead = TouchSListNode(data);
}
else //普通链表
{
PNode pTail = *ppHead;
while (pTail->_pNext)
{
pTail = pTail->_pNext;
}
pTail->_pNext = TouchSListNode(data);
}
}
void SListPopBack(PNode* ppHead)//尾删
{
assert(ppHead);//存在与否
if (NULL == *ppHead)//判空
return;
else if (NULL == (*ppHead)->_pNext)//链表只有一个结点
{
free(*ppHead);
*ppHead = NULL;
}
else//多个节点
{
PNode pTail = *ppHead;
PNode tmp = NULL;
while (pTail->_pNext)//直到找到一个节点的_pNext为0
{
tmp = pTail;
pTail = pTail->_pNext;
}
free(pTail);
tmp->_pNext = NULL;
}
}
void SListInsert(PNode *ppHead, PNode pos, DataType data) //任意位置插入//将data插入pos之前的位置
{
assert(ppHead);
PNode pNewNode = TouchSListNode(data);
if (NULL == *ppHead || NULL == pos)
return;
else if (pos == *ppHead)
{
pNewNode->_pNext = *ppHead;
*ppHead = pNewNode;
}
else
{
PNode pCur = *ppHead;
while (pCur && pCur->_pNext != pos)
{
pCur = pCur->_pNext;
}
if (pCur)
{
pCur->_pNext = pNewNode;
pNewNode->_pNext = pos;
}
}
}
void SListErase(PNode *ppHead, PNode pos)//任意位置的删除
{
assert(ppHead);
if (NULL == *ppHead || NULL == pos)
return;
if (pos == *ppHead)
{
*ppHead = pos->_pNext;
}
else
{
PNode pCur = *ppHead;
while (pCur && pCur->_pNext != pos)
{
pCur = pCur->_pNext;
}
if (pCur)
{
pCur->_pNext = pos->_pNext;
}
free(pos);
}
}
PNode FindPos(PNode pHead, DataType data)//找到第一个值为data的节点
{
assert(pHead);
if (NULL == pHead)
return NULL;
PNode pCur = pHead;
while (pCur)
{
if (pCur->_data == data)
return pCur;
pCur = pCur->_pNext;
}
return NULL;
}
void SListDestroy(PNode *ppHead)//正向销毁链表
{
assert(ppHead);
PNode pCur = *ppHead;
PNode pStr = NULL;
while (pCur)
{
pStr = pCur;
pCur = pCur->_pNext;
free(pStr);
}
*ppHead = NULL;
}
int SListSize(PNode pHead)//链表长度
{
int count = 0;
PNode pCur = pHead;
while (pCur)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
void TestSList( )//测试
{
int len;
PNode pHead,pCur;
SListInit(&pHead);//传地址才能改变内部参数
SListPushFront(&pHead, 1);
SListPushFront(&pHead, 2);
SListPushFront(&pHead, 3);
SListPushFront(&pHead, 4);
SListPushFront(&pHead, 5);
//SListPushFront(&pHead, 6);
//pCur = TouchSListNode(4);
//SListPopFront(&pHead);
//SListPushBack(&pHead, 0);
//SListPopBack(&pHead);
pCur = FindPos(pHead,2);
//SListInsert(&pHead, pCur, 9);
SListErase(&pHead, pCur);
len = SListSize(pHead);
printf("%d\n", len);
SListPrint(pHead);
//printf("%p\n", &pCur);
//SListPrint(pCur);
//PrintSListFromTail(pHead);
}
int main()
{
TestSList();
system("pause");
return 0;
}