链表的基础知识

//链表基础知识


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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值