SList.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DataType;
typedef struct SList
{
DataType data;
struct SList *p_next;
}SList,*PNode;
void SListInit(PNode* pHead);// 链表的初始化
void SListPushBack(PNode* pHead, DataType data);// 尾插
void SListPopBack(PNode* pHead);// 尾删
void SListPushFront(PNode* pHead, DataType data);// 头插
void SListPopFront(PNode* pHead);// 头删
PNode SListFind(PNode pHead, DataType data);// 在链表中查找值为data的元素,找到后返回值为data的结点
void SListInsert(PNode* pHead, PNode pos, DataType data);// 在pos位置插入值为data的结点
void SListErase(PNode* pHead, PNode pos);// 删除pos位置的结点
int SListSize(PNode pHead);// 获取链表的长度
int SListEmpty(PNode pHead);// 判断链表是否为空
void SListDestroy(PNode* pHead);// 销毁聊表
void PrintSList(PNode pHead);//打印链表的值
void PrintListTailToHead(PNode pHead);//逆序打印链表值
void DelNotTailNode(PNode pos);//删除链表节点
void InsertNotHead(PNode pos, DataType data);//在无头单链表的一个非头节点前插入一个节点
void FormCyc(PNode *pHead);//使链表形成一个环
PNode JosephCircle(PNode pHead, int M);//约瑟夫环
void yuesefu(PNode pHead,PNode pCur);//约瑟夫环输出
PNode FindelastkNode(PNode pHead,int k);//找到倒数第K个节点
void printfzhizhen(PNode pHead);//打印指针位置元素的值
void delastkNode(PNode pHead,int k);//删除倒数第K个节点
PNode FindelastkNode2(PNode pHead,int k);//返回前一个节点
void ReverseSList(PNode* pHead);//逆序链表
void maopao(PNode *pHead);//冒泡排序
SList.c
#include"SList.h"
PNode BuyNewNode(DataType data)
{
PNode pCur = NULL;
pCur = (PNode )malloc(sizeof(SList));
pCur->data = data;
return pCur;
}
void SListInit(PNode* pHead)// 链表的初始化
{
*pHead = NULL;
}
void SListPushBack(PNode* pHead, DataType data)// 尾插
{
PNode pCur = NULL;
PNode pRet = NULL;
assert(pHead);
if (*pHead == NULL)
{
*pHead =BuyNewNode(data);
(*pHead)->p_next = NULL;
return;
}
else
{
pCur = *pHead;
while (pCur->p_next)
{
pCur = pCur->p_next;
}
pRet = BuyNewNode(data);
pCur->p_next= pRet;
pRet->p_next = NULL;
}
return;
}
void SListPopBack(PNode* pHead)// 尾删
{
PNode pCur = *pHead;
PNode pPre = NULL;
assert(pHead);
if (*pHead == NULL)
{
printf("链表已空,无法删除!!!\n");
return;
}
while (pCur->p_next)
{
pPre = pCur;
pCur = pCur->p_next;
}
pPre->p_next = NULL;
free(pCur);
#if 0
while (pCur->p_next->p_next)
{
pCur = pCur->p_next;
}
PNode pNext = NULL;
pNext = pCur->p_next;
pCur->p_next = NULL;
free(pNext);
#endif
}
void SListPushFront(PNode* pHead, DataType data)// 头插
{
PNode pCur = *pHead;
PNode pRet = NULL;
assert(pHead);
if (*pHead == NULL)
{
*pHead = BuyNewNode(data);
(*pHead)->p_next = NULL;
}
else
{
pRet = BuyNewNode(data);
pRet->p_next = pCur;
*pHead = pRet;
}
}
void SListPopFront(PNode* pHead)// 头删
{
PNode pCur = NULL;
//判断pHead是否合法
assert(pHead);
//检测链表是否为空
if (NULL == *pHead)
{
printf("链表为空,无法删除!!!\n");
return;
}
else
{
//链表不为空
pCur = *pHead;
*pHead = (*pHead)->p_next;
free(pCur);
}
}
PNode SListFind(PNode pHead, DataType data)// 在链表中查找值为data的元素,找到后返回值为data的结点
{
PNode pCur = pHead;
//检测链表是否为空
if (pHead == NULL)
{
printf("链表中无元素!!!\n");
return NULL;
}
//链表不为空
while (pCur)
{
if (pCur->data == data)
return pCur;
pCur = pCur->p_next;
}
return NULL;
}
void SListInsert(PNode* pHead, PNode pos, DataType data)// 在pos位置插入值为data的结点
{
PNode pCur = *pHead;
PNode pRet = NULL;
PNode pPre = NULL;
//检测pHead合法性
assert(pHead);
//链表为空
if (*pHead == NULL )
{
printf("链表为空,无法插入!!!\n");
return;
}
if (pos == NULL)
{
printf("插入位置无效,无法插入!!!\n");
}
else
{
//链表不为空
pCur = *pHead;
while(pCur!=pos&&pCur)
{
pPre = pCur;
pCur = pCur->p_next;
}
if (pCur == NULL)
{
printf("链表中无该位置,无法插入!!!\n");
return;
}
else
{
pRet = BuyNewNode(data);
pRet->p_next = pCur;
pPre->p_next = pRet;
}
}
return;
}
void SListErase(PNode* pHead, PNode pos)// 删除pos位置的结点
{
PNode pCur = *pHead;
PNode pPre = NULL;
assert(pHead);
if (*pHead == NULL)
{
printf("链表为空,无法删除!!!\n");
return;
}
while (pCur != pos&&pCur)
{
pPre = pCur;
pCur = pCur->p_next;
}
if (!pCur)
{
printf("链表中无该结点!!!\n");
return;
}
else
{
pPre->p_next = pCur->p_next;
free(pCur);
}
}
int SListSize(PNode pHead)// 获取链表的长度
{
PNode pCur = pHead;
int count = 0;
if (pHead == NULL)
return 0;
while (pCur)
{
count++;
pCur = pCur->p_next;
}
return count;
}
int SListEmpty(PNode pHead)// 判断链表是否为空
{
if (pHead == NULL)
return 0;
else return 1;
}
void SListDestroy(PNode* pHead)// 销毁聊表
{
PNode pCur = *pHead;
PNode pPre = NULL;
assert(pHead);
if (*pHead == NULL)
return;
while (pCur)
{
pPre = pCur;
pCur = pCur->p_next;
free(pPre);
}
*pHead = NULL;
}
void PrintSList(PNode pHead)//打印链表的值
{
PNode pCur = NULL;
pCur = pHead;
while (pCur)
{
printf("%d ", pCur->data);
pCur = pCur->p_next;
}
printf("\n");
}
//逆序打印链表
//原理:通过函数自己调用自己,
void PrintListTailToHead(PNode pHead)
{
if(pHead != NULL)
{
PrintListTailToHead(pHead->p_next);
//执行到这里返回,直到next为空,为空进入
//下一个if else 表达式,返回时候的函数就返回到这里继续执行
if(pHead->p_next == NULL)
printf("%d",pHead->data);
else
{
printf("->%d",pHead->data);
}
}
}
//删除一个无头单链表的非尾节点
void DelNotTailNode(PNode pos)
{
PNode cur = NULL;
assert(pos);
if(NULL == pos ->p_next)
return;
else
{
DataType temp = 0;
//交换pos和pos->n_next的数据,问题变成删除pos指向的节点的下一个节点
temp = pos->data;
pos->data = pos->p_next->data;
pos->p_next->data = temp;
cur = pos->p_next;
pos->p_next = pos->p_next->p_next;
free(cur);
cur = NULL;
}
}
void InsertNotHead(PNode pos, DataType data)//在无头单链表的一个非头节点前插入一个节点
{
PNode cur;
DataType i;
assert(pos);
i = pos->data;
pos->data = data;
data = i;
cur = BuyNewNode(data);
cur->p_next = pos->p_next;
pos->p_next = cur;
}
void FormCyc(PNode *pHead)//使链表形成一个环
{
PNode cur = *pHead;
assert(pHead);
while(cur->p_next)
{
cur = cur->p_next;
}
cur ->p_next = (*pHead);
}
PNode JosephCircle(PNode pHead, int M)//约瑟夫环
{
PNode cur = pHead;
PNode per = NULL;
PNode der = NULL;
DataType temp = M;
if ((NULL == pHead) || (M <=0))
{
return NULL;
}
else
{
FormCyc(&pHead);
while(cur->p_next != cur)
{
temp = M;
per = cur;
while(temp)
{
per = cur;
cur = cur ->p_next;
--temp;
}
der = cur;
cur = cur->p_next;
per->p_next = cur;
free(der);
der = NULL;
}
if(M == 1)
{
free(cur);
cur = NULL;
return NULL;
}
else
{
cur -> p_next = NULL;
}
return cur;
}
}
void yuesefu(PNode pHead,PNode pCur)//约瑟夫环输出
{
PNode t = pHead;
if(pCur == NULL)
{
printf("输入错误或输入为1,剩下的节点为%d\n ",t->data);
}
else
{
printf("剩余的节点为%d\n",pCur->data);
}
}
PNode FindelastkNode(PNode pHead,int k)
{
PNode pFast = pHead;
PNode last = pHead;
if(pHead == NULL || k <=0 )
{
return NULL;
}
while(k--)
{
if(pFast == NULL)
{
printf("K大于链表中节点个数");
return NULL;
}
pFast = pFast->p_next;
}
//慢指针一起走
while(pFast)
{
last = last->p_next;
pFast = pFast->p_next;
}
return last;
}
PNode FindelastkNode2(PNode pHead,int k)//返回前一个节点
{
PNode pFast = pHead;
PNode last = pHead;
PNode per = NULL;
if(pHead == NULL || k <=0 )
{
return NULL;
}
while(k--)
{
if(pFast == NULL)
{
printf("K大于链表中节点个数");
return NULL;
}
pFast = pFast->p_next;
}
//慢指针一起走
while(pFast)
{
per = last;
last = last->p_next;
pFast = pFast->p_next;
}
return per;
}
void printfzhizhen(PNode t)//打印指针位置元素的值
{
printf("节点值为%d\n",t->data);
}
void delastkNode(PNode pHead,int k)//删除倒数第K个节点
{
PNode cur;
PNode pur;
cur = FindelastkNode2(pHead,k);
pur = cur->p_next;
cur ->p_next = pur->p_next;
free(pur);
}
void ReverseSList(PNode* pHead)
{
PNode pur,cur,tur;
assert(pHead);
pur = NULL;
cur = *pHead;
tur = NULL;
while(cur)
{
tur = cur->p_next;
cur->p_next = pur;
pur = cur;
cur = tur;
}
(*pHead) = pur;
}
void maopao(PNode *pHead)
{
PNode pur,cur,tur;
int i;
int max = 0;
pur = NULL;
tur = (*pHead);
while(tur)
{
cur = *pHead;
max = cur->data;
while(cur)
{
if(cur->p_next == NULL)
break;
if( cur->p_next->data < cur->data)
{
max = cur->data;
cur ->data = cur->p_next->data;
cur->p_next->data = max;
}
cur = cur->p_next;
}
tur = tur->p_next;
}
}
Test.c
#include"SList.h"
int main()
{
SList List;
PNode pHead ;
PNode pCur = NULL;
SListInit(&pHead);//链表初始化
//尾插测试
SListPushBack(&pHead, 5);
SListPushBack(&pHead, 6);
SListPushBack(&pHead, 7);
SListPushBack(&pHead, 8);
SListPushBack(&pHead, 9);
PrintSList(pHead); //打印
//头插测试
SListPushFront(&pHead, 4);
SListPushFront(&pHead, 3);
SListPushFront(&pHead, 2);
SListPushFront(&pHead, 1);
SListPushFront(&pHead, 0);
PrintSList(pHead); //打印
//PrintListTailToHead(5);
PrintListTailToHead(pHead);//逆序打印
printf("\n");
pCur = SListFind(pHead, 2); //先获取pos位置
DelNotTailNode(pCur);
PrintSList(pHead);
pCur = SListFind(pHead, 3);
InsertNotHead(pCur, 8);//在无头单链表的一个非头节点前插入一个节点
PrintSList(pHead);
/*ReverseSList(&pHead);
printf("haha");*/
PrintSList(pHead);
maopao(&pHead);
PrintSList(pHead);
// pCur = JosephCircle(pHead, 8);
// yuesefu(pHead,pCur);//约瑟夫环的输出
// pCur = FindelastkNode(pHead,5);
// printfzhizhen(pCur);
// PrintSList(pHead);
//delastkNode(pHead,9);//删除倒数第K个节点
//PrintSList(pHead);
任意位置插入测试
// pCur = SListFind(pHead, 2); //先获取pos位置
//SListInsert(&pHead, pCur, 10); PrintSList(pHead);//打印
//SListInsert(&pHead, NULL, 100); PrintSList(pHead);//打印
任意位置删除
//pCur = SListFind(pHead, 10);
//SListErase(&pHead, pCur); PrintSList(pHead); //打印
尾删测试
//SListPopBack(&pHead); PrintSList(pHead);//打印
头删测试
//SListPopFront(&pHead); PrintSList(pHead);//打印
打印链表的长度
//printf("链表长度是:%d\n",SListSize(pHead));
判断链表是否为空
//printf("链表是否为空:%d\n", SListEmpty(pHead));
销毁链表
//SListDestroy(&pHead);
再次判断是否为空
//printf("链表是否为空:%d\n", SListEmpty(pHead));
system("pause");
return 0;
}