用C语言来实现一个单向链表的增、查、改、删。以及约瑟夫环,链表倒置,插入排序等
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
typedef int DataType;//一是表明该类型的特殊作用,二是将来有可能要改变这种类型(比如提高精度),可以统一修改
typedef struct Node
{
DataType Data;
struct Node *pNext;
}LinkNode;
typedef struct List
{
LinkNode *pHead;
int cLen;
}LinkList;
//判空函数
bool isEmptyLinkList(LinkList *pList)
{
return pList->pHead == NULL;
}
//创建一个链表
LinkList *createLinkList()
{
LinkList *pList = malloc(sizeof(LinkList));
//为了解决C语言中NULL代指空指针存在的二义性问题,在C++11版本(2011年发布)中特意引入了
//nullptr这一新的关键字来代指空指针
if(NULL == pList)
{
perror("fail to create!");
}
pList->pHead = NULL;
pList->cLen = 0;
return pList;
}
//头插
int insertHeadLinkList(LinkList *pList, DataType value)
{
LinkNode *pNew = malloc(sizeof(LinkNode));
if(NULL == pNew)
{
perror("fail to create!");
return -1;
}
pNew->Data = value;
pNew->pNext = pList->pHead;
pList->pHead = pNew;
++pList->cLen;
return 0;
}
//尾插
int insertTailLinkList(LinkList *pList, DataType value)
{
if(isEmptyLinkList(pList))
{
insertHeadLinkList(pList,value);
}
else
{
LinkNode *pNew = malloc(sizeof(LinkNode));
if(NULL == pNew)
{
perror("fail to create!");
return -1;
}
pNew->Data = value;
pNew->pNext = NULL;
LinkNode *pTemp = pList->pHead;
while(pTemp->pNext != NULL)
{
pTemp = pTemp->pNext;
}
pTemp->pNext = pNew;
++pList->cLen;
}
return 0;
}
//头删
int deleteHeadLinkList(LinkList *pList)
{
if(!isEmptyLinkList(pList))
{
LinkNode *pTemp = pList->pHead;
pList->pHead = pTemp->pNext;
free(pTemp);
--pList->cLen;
}
return 0;
}
//尾删
int deleteTailLinkList(LinkList *pList)
{
if(!isEmptyLinkList(pList))
{
if(1 == pList->cLen)
{
deleteHeadLinkList(pList);
}
else if(2 <= pList->cLen)
{
LinkNode *pTemp = pList->pHead;
while(pTemp->pNext->pNext != NULL)
{
pTemp = pTemp->pNext;
}
free(pTemp->pNext);
pTemp->pNext = NULL;
--pList->cLen;
}
}
return 0;
}
//查找
LinkNode *findLinkNode(LinkList *pList, DataType value)
{
if(!isEmptyLinkList(pList))
{
LinkNode *pTemp = pList->pHead;
while(pTemp != NULL)
{
if(pTemp->Data == value)
{
return pTemp;
}
pTemp = pTemp->pNext;
}
if(pTemp == NULL)
{
printf("no find!\n");
}
return NULL;
}
else
{
printf("List is empty!\n");
}
return NULL;
}
//修改链表数据
int modifyLinkList(LinkList *pList, int oldValue, DataType newValue)
{
LinkNode *pTemp = findLinkNode(pList, oldValue);
if(pTemp != NULL)
{
pTemp->Data = newValue;
return 1;
}
return 0;
}
//打印链表中结点个数及各结点数据
void showLinkList(LinkList *pList)
{
if(isEmptyLinkList(pList))
{
printf("Linklist is empty!\n");
}
else
{
printf("Linklist's cLen:%d\n",pList->cLen);
LinkNode *pTemp = pList->pHead;
printf("Linklist's data:");
while(pTemp != NULL)
{
printf("%d ",pTemp->Data);
pTemp = pTemp->pNext;
}
printf("\n");
}
}
//摧毁链表
void destroyLinkList(LinkList **ppList)
{
if(isEmptyLinkList(*ppList))
{
free(*ppList);
}
else
{
while((*ppList)->pHead != NULL)
{
deleteHeadLinkList(*ppList);
}
free(*ppList);
*ppList = NULL;
}
}
//快慢指针法求链表的中间结点
LinkNode *findMidLinkList(LinkList *pList)
{
LinkNode *pFast = pList->pHead;
LinkNode *pSlow = pList->pHead;
while(pFast != NULL)
{
pFast = pFast->pNext;
if(pFast == NULL)
{
break;
}
else
{
pFast = pFast->pNext;
pSlow = pSlow->pNext;
}
}
return pSlow;
}
//寻找链表倒数第K个数据
LinkNode *FindLastKNode(LinkList *pList, DataType k)
{
LinkNode *pFast = pList->pHead;
LinkNode *pSlow = pList->pHead;
for(int i = 0;i < k;++i)
{
pFast = pFast->pNext;
}
while(pFast != NULL)
{
pFast = pFast->pNext;
pSlow = pSlow->pNext;
}
return pSlow;
}
//判断链表是否为环形
int isLoopLinkList(LinkList *pList)
{
LinkNode *pFast = pList->pHead;
LinkNode *pSlow = pFast;
while(pFast != NULL)
{
pFast = pFast->pNext;
if(pFast == NULL)
{
return 0;
}
pFast = pFast->pNext;
pSlow = pSlow->pNext;
if(pFast == pSlow)
{
return 1;
}
}
return 0;
}
//约瑟夫环
LinkNode *joseF(LinkList *pList)
{
LinkNode *pTmpNode = pList->pHead;
LinkNode *pPreNode = NULL;
while(pList->cLen > 1)
{
pPreNode = pTmpNode;
pTmpNode = pTmpNode->pNext->pNext;
pPreNode = pPreNode->pNext;
pPreNode->pNext = pTmpNode->pNext;
free(pTmpNode);
pTmpNode = pPreNode->pNext;
--pList->cLen;
}
return pTmpNode;
}
//链表倒置
void reverseLinkList(LinkList *pList)
{
LinkNode *pTmpNode = pList->pHead;
LinkNode *pInsertNode = NULL;
pList->pHead = NULL;
while(pTmpNode != NULL)
{
pInsertNode = pTmpNode;
pTmpNode = pTmpNode->pNext;
pInsertNode->pNext = pList->pHead;
pList->pHead = pInsertNode;
}
}
//删除链表指定位置的结点
int deleteKLinkList(LinkList *pList, DataType value)
{
if(isEmptyLinkList(pList))
{
return 0;
}
LinkNode *pTmpNode = pList->pHead;
LinkNode *pPreNode = pList->pHead;
while(pTmpNode != NULL)
{
if(pTmpNode->Data == value)
{
if(pTmpNode == pPreNode)
{
pList->pHead = pPreNode->pNext;
free(pTmpNode);
pTmpNode = pList->pHead;
pPreNode = pList->pHead;
}
else
{
pPreNode->pNext = pTmpNode->pNext;
free(pTmpNode);
pTmpNode = pPreNode->pNext;
}
--pList->cLen;
}
else
{
pPreNode = pTmpNode;
pTmpNode = pTmpNode->pNext;
}
}
return 1;
}
//插入排序
int insertSortLinkList(LinkList *pList)
{
if(isEmptyLinkList(pList) || pList->cLen == 1)
{
return 0;
}
//将链表从第一个结点断开
LinkNode *pTmpNode = pList->pHead->pNext;
LinkNode *pInsertNode = NULL;
pList->pHead->pNext = NULL;
while(pTmpNode != NULL)
{
pInsertNode = pTmpNode;
pTmpNode = pTmpNode->pNext;
pInsertNode->pNext = NULL;
if(pInsertNode->Data < pList->pHead->Data)
{
pInsertNode->pNext = pList->pHead;
pList->pHead = pInsertNode;
}
else
{
LinkNode *pTemp = pList->pHead;
while(pTemp!=NULL && pTemp->pNext!=NULL && pTemp->pNext->Data < pInsertNode->Data)
{
pTemp = pTemp->pNext;
}
pInsertNode->pNext = pTemp->pNext;
pTemp->pNext = pInsertNode;
}
}
return 0;
}
//主函数
int main(void)
{
LinkList *pList = NULL;
pList = createLinkList(); //创建链表
insertHeadLinkList(pList, 10); //插入数据
insertTailLinkList(pList, 30);
insertTailLinkList(pList, 20);
insertTailLinkList(pList, 40);
insertTailLinkList(pList, 60);
insertTailLinkList(pList, 50);
insertTailLinkList(pList, 70);
insertTailLinkList(pList, 80);
showLinkList(pList);
deleteKLinkList(pList,20);
showLinkList(pList);
insertSortLinkList(pList);
showLinkList(pList);
// reverseLinkList(pList); //链表倒置
// showLinkList(pList);
// deleteTailLinkList(pList); //删除尾部数据
// showLinkList(pList);
// deleteHeadLinkList(pList); //删除头部数据
// showLinkList(pList);
// modifyLinkList(pList, 20, 50); //将链表中的第一个20修改为50
// showLinkList(pList);
// LinkNode *pTmp = NULL;
// pTmp = findLinkNode(pList, 30);//寻找链表中的30
// destroyLinkList(&pList); //摧毁链表
// LinkNode *pFindMid = NULL;
// pFindMid = findMidLinkList(pList);
// printf("%d\n",pFindMid->Data);
// LinkNode *pFindKLast = NULL;
// pFindKLast = FindLastKNode(pList, 3);
// printf("%d\n",pFindKLast->Data);
return 0;
}
再来一个双向链表
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
//双向链表
typedef struct Student
{
int id;
int score;
char name[32];
}DataTpye;
typedef struct Node
{
DataTpye data;
struct Node *pPre;//不能在typedef类型之前使用它,如 DouNode *pPre;
struct Node *pNext;
}DouNode;
typedef struct List
{
int cLen;
DouNode *pHead;
}DouList;
//创建双向链表
DouList *createDouList()
{
DouList *pList = malloc(sizeof(DouList));
if(pList == NULL)
{
perror("fail to create!");
}
pList->cLen = 0;
pList->pHead = NULL;
return pList;
}
//判空函数
bool isEmptyDouList(DouList *pList)
{
return (pList->pHead == NULL);
}
//显示双向链表数据
void showDouList(DouList *pList, int dir)
{
if(isEmptyDouList(pList))
{
return ;
}
DouNode *pTemp = pList->pHead;
if(dir == 1)
{
printf("cLen's number:%d\n",pList->cLen);
while(pTemp != NULL)
{
printf("%s %d %d\n", pTemp->data.name, pTemp->data.id, pTemp->data.score);
pTemp = pTemp->pNext;
}
}
else if(dir == 0)
{
printf("cLen's number:%d\n",pList->cLen);
while(pTemp->pNext != NULL)
{
pTemp = pTemp->pNext;
}
while(pTemp != NULL)
{
printf("%s %d %d\n", pTemp->data.name, pTemp->data.id, pTemp->data.score);
pTemp = pTemp->pPre;
}
}
printf("\n");
}
//头插
int insertHeadDouNode(DouList *pList, DataTpye *pdata)
{
DouNode *pNew = malloc(sizeof(DouNode)); //必须得在堆区开辟空间
memcpy(&pNew->data, pdata, sizeof(DataTpye));
pNew->pPre = NULL;
pNew->pNext = pList->pHead;
if(pList->pHead != NULL)
{
pList->pHead->pPre = pNew;
}
pList->pHead = pNew;
++pList->cLen;
return 1;
}
//尾插
int insertTailDouNode(DouList *pList, DataTpye *pdata)
{
if(pList->pHead == NULL)
{
insertHeadDouNode(pList, pdata);
}
if(pList->cLen >= 1)
{
DouNode *pNew = malloc(sizeof(DouNode));
memcpy(&pNew->data, pdata, sizeof(DataTpye));
pNew->pNext = NULL;
DouNode *pTemp = pList->pHead;
while(pTemp->pNext != NULL)
{
pTemp = pTemp->pNext;
}
pTemp->pNext = pNew;
pNew->pPre = pTemp;
++pList->cLen;
}
return 1;
}
//头删
int deleteHeadNodList(DouList *pList)
{
if(!isEmptyDouList(pList))
{
DouNode *pTemp = pList->pHead;
pList->pHead = pTemp->pNext;
if(pTemp->pNext != NULL)
{
pTemp->pNext->pPre = NULL;
}
free(pTemp);
--pList->cLen;
}
return 1;
}
//尾删
int deleteTailNodList(DouList *pList)
{
if(isEmptyDouList(pList))
{
return 0;
}
if(pList->cLen == 1)
{
deleteHeadNodList(pList);
}
if(pList->cLen > 1)
{
DouNode *pTemp = pList->pHead;
while(pTemp->pNext != NULL)
{
pTemp = pTemp->pNext;
}
pTemp->pPre->pNext = NULL;
free(pTemp);
--pList->cLen;
}
return 1;
}
//摧毁链表
void destroyDouList(DouList **ppList)
{
if((*ppList)->pHead != NULL)
{
deleteHeadNodList(*ppList);
}
free(*ppList);
*ppList = NULL;
}
int main(void)
{
DouList *pList = NULL;
pList = createDouList();//创建链表
DataTpye stu[3] = {{1, 99, "zhangsan"}, {2, 91, "lisi"}, {3, 92, "wangwu"}};
insertHeadDouNode(pList, &stu[0]);
insertHeadDouNode(pList, &stu[1]);
insertTailDouNode(pList, &stu[2]);
showDouList(pList, 1);
deleteTailNodList(pList);
deleteHeadNodList(pList);
showDouList(pList, 1);
}