typedef int DataType;
typedef struct ListNode
{
struct ListNode* _pNext;
DataType _data;
}ListNode,*PNode;
// 链表的初始化
void SListInit(PNode* pHead);
//创建新结点
PNode BuyNewNode(DataType data);
// 尾插
void SListPushBack(PNode* pHead, DataType data);
// 尾删
void SListPopBack(PNode* pHead);
// 头插
void SListPushFront(PNode* pHead, DataType data);
// 头删
void SListPopFront(PNode* pHead);
// 在链表中查找值为data的元素,找到后返回值为data的结点
PNode SListFind(PNode pHead, DataType data);
//求链表结点个数
int SListSize(PNode phead);
// 在pos位置插入值为data的结点
void SListInsert(PNode* pHead, int pos, DataType data);
// 删除pos位置的结点
void SListErase(PNode* pHead, int pos);
// 获取链表中值data的结点
int SListDataSize(PNode pHead,DataType data);
// 判断链表是否为空
int SListEmpty(PNode pHead);
// 销毁链表
void SListDestroy(PNode* pHead);
///////////////////////////////////////////////////////////////
//测试函数
void testSListInit(); //测试初始化
void testPushTail(); //测试尾插
void testSListPopBack(); //测试尾删
void testPushFront(); //测试头插
void testPopFront(); //测试头删
void testFind(); //测试找到值为data的结点,返回结点
void testInsert(); //测试在pos位置插入data
void testErase(); //测试删除pos位置结点
void testDataSize(); //测试获取值为data的结点
void testEmptyAndDestory(); ////测试摧毁链表和判断链表是否为空
// 链表的初始化
void SListInit(PNode* pHead)
{
assert(pHead);
*pHead = NULL; //将结点赋空
}
//创建新结点
PNode BuyNewNode(DataType data)
{
PNode pNew = NULL;
pNew = (PNode)malloc(sizeof(PNode)); //申请一块新结点的空间
if (NULL == pNew) //判断是否申请成功
{
printf("申请结点失败!!\n");
return NULL;
}
pNew->_data = data;
pNew->_pNext = NULL;
return pNew;
}
// 尾插
void SListPushBack(PNode* pHead, DataType data)
{
assert(pHead);
PNode pCur;
PNode tail = BuyNewNode(data); //创建新结点
pCur = *pHead;
if (NULL == pCur) // 判断头结点是否为空
{
*pHead = tail;
}
else{
while (pCur->_pNext) // 遍历链表 找到最后一个结点
{
pCur = pCur->_pNext;
}
pCur->_pNext = tail; //将最后结点的下一个结点改为新结点
}
}
// 尾删
void SListPopBack(PNode* pHead)
{
assert(pHead);
PNode pCur = NULL;
PNode pDel = NULL;
pCur = *pHead;
pDel = pCur->_pNext;
if (NULL == *pHead) //判断链表是否为空
return;
else if (pCur->_pNext == NULL) //只有一个结点 直接令其为空
{
*pHead = NULL;
}
else
{
while (pDel->_pNext) //遍历链表,找到最后结点
{
pCur = pDel;
pDel = pDel->_pNext;
}
}
//free(pDel); //防止野指针的产生
pCur->_pNext = NULL; // 让最后一个结点为空
}
// 头插
void SListPushFront(PNode* pHead, DataType data)
{
assert(pHead);
PNode pNewHead;
PNode pCur;
pCur = *pHead;
pNewHead = BuyNewNode(data); //创建新结点
if (NULL == *pHead)
{
*pHead = pNewHead; //空链表,直接将新结点赋给原结点
}
else
{
DataType tem;
pNewHead->_pNext = pCur->_pNext; //先将new与后面链接
pCur->_pNext = pNewHead; //使phead下一个结点指向新结点
tem = pNewHead->_data; //交换两个结点的data
pNewHead->_data = pCur->_data;
pCur->_data = tem;
}
}
// 头删
void SListPopFront(PNode* pHead)
{
assert(pHead);
PNode pCur;
PNode pDel;
pCur = *pHead;
if (NULL == *pHead) //处理头结点
return;
else if (NULL == pCur->_pNext) //处理 只有一个结点
{
*pHead = NULL;
}
else //处理多个结点
{
pDel = pCur->_pNext;
DataType tem = pCur->_data;
pCur->_data = pDel->_data;
pDel->_data = tem; //交换data 删除第二个结点, 相当于删除第一个结点
pCur->_pNext = pDel->_pNext;
free(pDel); //释放删除后的结点
}
}
// 在链表中查找值为data的元素,找到后返回值为data的结点
PNode SListFind(PNode pHead, DataType data)
{
//assert(pHead);
PNode pCur;
pCur = pHead;
if (pHead == NULL) //处理空链表
{
return NULL;
}
else
{
while (pCur->_pNext) //遍历链表
{
if (pCur->_data == data)
{
return pCur; //找到值为data的结点 并返回
}
pCur = pCur->_pNext;
}
return NULL; //没找到值为data的结点 返回空
}
}
//求链表结点个数
int SListSize(PNode phead)
{
PNode pCur;
int flag = 0;
pCur = phead;
while (pCur)
{
pCur = pCur->_pNext;
flag++;
}
return flag;
}
// 在pos位置插入值为data的结点
void SListInsert(PNode* pHead, int pos, DataType data)
{
assert(pHead);
PNode pCur;
PNode pNew;
int size = 0;
pNew = BuyNewNode(data);
pCur = *pHead;
size = SListSize(*pHead);
if (size == 0) //处理空链表
{
return;
}
else
{
while (--pos && pCur) //遍历链表 找到pos位置或者pcur为null
{
pCur = pCur->_pNext;
}
if (pCur == NULL) //处理pcur为空
{
return;
}
else // 找到pos位置,插入到pcur后面,再交换二者数据
{
pNew->_pNext = pCur->_pNext;
pCur->_pNext = pNew;
int tem = 0;
tem = pNew->_data;
pNew->_data = pCur->_data;
pCur->_data = tem;
}
}
}
// 删除pos位置的结点
void SListErase(PNode* pHead, int pos)
{
assert(pHead);
PNode pCur;
PNode pDel = NULL;
int size;
pCur = *pHead;
size = SListSize(*pHead);
if (size == 0)
{
return;
}
while (--pos && pCur)
{
pCur = pCur->_pNext;
}
if (pCur == NULL)
{
return;
}
else
{
pDel = pCur->_pNext;
if (pDel == NULL)
{
SListPopBack(pHead);
}
else
{
pCur->_pNext = pDel->_pNext;
pCur->_data = pDel->_data;
//free(pDel);
}
}
}
// 获取链表中值data的结点
int SListDataSize(PNode pHead, DataType data)
{
PNode pCur;
int count = 0;
pCur = pHead;
if (pHead == NULL) //测试空链表
{
return -1;
}
else
{
while (pCur->_data != data) //找到data 或者 遍历完链表后跳出循环
{
pCur = pCur->_pNext;
count++;
if (pCur == NULL)
{
return -1;
}
}
}
return count + 1; //返回data处在第几个结点
}
// 判断链表是否为空
int SListEmpty(PNode pHead)
{
if (pHead == NULL)
return 0;
else
return 1;
}
// 销毁链表
void SListDestroy(PNode* pHead)
{
assert(pHead);
PNode pCur;
pCur = *pHead;
if (*pHead == NULL)
return;
else if (pCur->_pNext == NULL)
{
free(pCur);
}
else
{
pCur = pCur->_pNext;
SListDestroy(&pCur);
}
}
////////////////////////////////////////////////////////
//测试初始化
void testSListInit()
{
PNode pHead;
SListInit(&pHead);
}
//测试尾插
void testPushTail()
{
PNode phead;
SListInit(&phead);
SListPushBack(&phead, 5);
}
//测试尾删
void testSListPopBack()
{
PNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
SListPopBack(&pHead);
}
//测试头插
void testPushFront()
{
PNode pHead;
SListInit(&pHead);
SListPushFront(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushFront(&pHead, 0);
}
//测试头删
void testPopFront()
{
PNode pHead;
SListInit(&pHead);
SListPopFront(&pHead); //测试空链表头删
SListPushBack(&pHead, 1);
SListPopFront(&pHead); //测试只有一个结点头删
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushFront(&pHead, 1); //头插
SListPopFront(&pHead); // 测试多个结点头删
SListPushBack(&pHead, 4);
}
//测试找到值为data的结点,返回结点
void testFind()
{
PNode pHead;
PNode pFind;
SListInit(&pHead);
SListInit(&pFind);
pFind = SListFind(pHead, 1); //测试空链表
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
pFind = SListFind(pHead, 2); // 测试找到data
pFind = SListFind(pHead, 5); //测试没找到data
}
//测试在pos位置插入data
void testInsert()
{
PNode pHead;
SListInit(&pHead);
SListInsert(&pHead, 2, 1); //测试空链表
SListPushBack(&pHead, 0);
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListInsert(&pHead, 6, 5); //测试pos大于结点个数
SListInsert(&pHead, 3, 9); //测试pos小于结点个数
}
//测试删除pos位置结点
void testErase()
{
PNode pHead;
SListInit(&pHead);
SListErase(&pHead, 2); //测试空链表
SListPushBack(&pHead, 0);
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListErase(&pHead, 4); //测试删除最后一个结点
SListErase(&pHead, 5); //pos 大于 结点个数
SListErase(&pHead, 2); // pos小于 结点个数
}
//测试获取值为data的结点
void testDataSize()
{
PNode pHead;
SListInit(&pHead);
SListDataSize(pHead, 2); // 空链表
SListPushBack(&pHead, 0);
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListDataSize(pHead, 5); //没data 值
SListDataSize(pHead, 3); //有data值
}
//测试摧毁链表和判断链表是否为空
void testEmptyAndDestory()
{
PNode pHead;
SListInit(&pHead);
SListEmpty(pHead);
SListPushBack(&pHead, 0);
SListPushBack(&pHead, 0);
SListPushBack(&pHead, 0);
SListEmpty(pHead);
SListDestroy(&pHead);
}