LinkList.h
#ifndef __LINK_LIST_H__
#define __LINK_LIST_H__
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DataType;//定义数据类型
typedef struct Node
{
DataType data;
struct Node* pNext;
}Node, *PNode;
//初始化链表
void InitLinkList(PNode* pHead);
//给链表创建新结点
PNode BuyNode(DataType x);
//正向打印链表
void PrintLinkList(PNode pHead);
//给链表尾插
void PushBack(PNode* pHead, DataType x);
//返回结点在链表中的位置
PNode Find(PNode pHead, DataType x);
//任意位置插入值为x的结点
PNode Insert(PNode pos, DataType x);
// 删除pos位置上的结点
void Erase(PNode* pHead, PNode pos);
//删除单链表的非尾节点
void DeleteNotpTailNode(PNode pos);
//非头结点前插入data
void InsertNotHead(PNode pos, DataType x);
//单链表的逆置——前后指针(定义三个指针)
PNode ReverseLinkList(PNode pHead);
//单链表的逆置——头插法
PNode ReverseLinkList(PNode pHead);
//查找链表的中间节点--要求不能遍历单链表
PNode FindMidNode(PNode pHead);
#endif//__LINK_LIST_H__
LinkList.c
#include"LinkList.h"
//初始化链表
void InitLinkList(PNode* pHead)
{
assert(*pHead);
(*pHead) = NULL;
}
//给链表创建新结点
PNode BuyNode(DataType x)
{
PNode pCur = (PNode)malloc(sizeof(Node));
if (NULL == pCur)
return NULL;
else
{
pCur->data = x;
pCur->pNext = NULL;
return pCur;
}
}
//正向打印链表
void PrintLinkList(PNode pHead)
{
if (NULL == pHead)
printf("null\n");
else
{
while (pHead)
{
printf("%d--->", pHead->data);
pHead = pHead->pNext;
}
printf("NULL\n");
}
}
//给链表尾插
void PushBack(PNode* pHead, DataType x)//尾插函数
{
PNode pTail = *pHead;
PNode pCur = BuyNode(x);
if (NULL == (*pHead))
*pHead = pCur;
else
{
while (pTail->pNext)
{
pTail = pTail->pNext;
}
pTail->pNext = pCur;
}
}
//返回结点在链表中的位置
PNode Find(PNode pHead, DataType x)
{
PNode pCur = pHead;
PNode pPreCur = NULL;
assert(pHead);
if (NULL == pHead)
return NULL;
while (pCur)
{
if (pCur->data == x)
{
pPreCur = pCur;
return pPreCur;
}
else
{
pCur = pCur->pNext;
}
}
return NULL;
}
//任意位置插入值为x的结点
PNode Insert(PNode pos, DataType x)
{
PNode pCur = NULL;
if (NULL == pos)
return NULL;
pCur = BuyNode(x);
if (NULL == pCur)
return NULL;
pCur->pNext = pos->pNext;
pos->pNext = pCur;
}
// 删除pos位置上的结点
void Erase(PNode* pHead, PNode pos)
{
assert(pHead);//判断空指针
if (NULL ==(*pHead)&&NULL == pos)//判断空链表和pos是否为空指针,无论满足那个,都直接返回空指针
return;
if ((*pHead) == pos)
{
free(*pHead);
(*pHead) = NULL;
}
else
{
PNode pCur = *pHead;
while (pCur->pNext != pos)
{
pCur = pCur->pNext;
}
pCur->pNext = pos->pNext;
free(pos);
pos = NULL;
}
}
//删除单链表的非尾节点(要删除pos位置的节点,只能删除pos下一个节点,因为不能遍历链表,如果pos直接删除,链表就会断)
void DeleteNotpTailNode(PNode pos)
{
PNode pCur = pos->pNext;
if (NULL == pos&&NULL==pos->pNext)
return;
pos->data = pCur->data;
pos->pNext = pCur->pNext;
free(pCur);
pCur = NULL;
}
//非头结点前插入data
void InsertNotHead(PNode pos, DataType x)
{
PNode pPreCur = NULL;
DataType temp = 0;
if (NULL == pos)
return;
pPreCur = BuyNode(x);
if (NULL == pPreCur)
return;
pPreCur->pNext = pos->pNext;
pos->pNext = pPreCur;
temp = pos->data;
pos->data = pPreCur->data;
pPreCur->data = temp;
}
//单链表的逆置——前后指针(定义三个指针)
PNode ReverseLinkList1(PNode pHead)
{
PNode pPreCur = NULL;
PNode pCur = NULL;
PNode pTail = NULL;
assert(pHead);
if (NULL == pHead&&pHead->pNext)
return pHead;
pPreCur = pHead;
pCur = pHead->pNext;
pTail = pHead->pNext->pNext;
pHead->pNext = NULL;//记得把pHead后一个置为空,否则,会无限循环
while (pTail)
{
pCur->pNext = pPreCur;
pPreCur = pCur;
pCur = pTail;
pTail = pTail->pNext;
}
pCur->pNext = pPreCur;
return pCur;
}
//单链表的逆置——头插法
PNode ReverseLinkList(PNode pHead)
{
PNode pPreCur = NULL;
PNode pCur = NULL;
PNode pTail = NULL;
if (NULL == pHead&&NULL == pHead)
return pHead;
pPreCur = pHead;
pCur = pHead->pNext;
while (pCur)
{
pPreCur->pNext = pTail;
pTail = pPreCur;
pPreCur = pCur;
pCur = pCur->pNext;
}
pPreCur->pNext = pTail;
pTail = pPreCur;
return pTail;
}
//查找链表的中间节点--要求不能遍历单链表
PNode FindMidNode(PNode pHead)
{
assert(pHead);
PNode pFast = NULL;
PNode pSlow = NULL;
if (NULL == pHead&&pHead->pNext)
return NULL;
pFast = pHead;
pSlow = pHead;
while (pFast&&pFast->pNext)
{
pFast = pFast->pNext->pNext;
pSlow = pSlow->pNext;
}
return pSlow;
}
test.c
#include"LinkList.h"
void test()
{
PNode pHead;
PNode p;
PNode p2;
PNode p3;
PNode p4;
InitLinkList(&pHead);
PushBack(&pHead, 1);//尾插
PushBack(&pHead, 2);//尾插
PushBack(&pHead, 3);//尾插
PushBack(&pHead, 4);//尾插
PushBack(&pHead, 5);//尾插
PushBack(&pHead, 6);//尾插
PushBack(&pHead, 7);//尾插
PrintLinkList(pHead);//正向打印链表
//返回结点在链表中的位置
p=Find(pHead, 5);
printf("%d\n", p->data);
//任意位置插入值为x的结点
Insert(Find(pHead, 2), 9);
PrintLinkList(pHead);//正向打印链表
// 删除pos位置上的结点
Erase(&pHead, Find(pHead,3));
PrintLinkList(pHead);//正向打印链表
//删除单链表的非尾节点
DeleteNotpTailNode(Find(pHead,4));
PrintLinkList(pHead);//正向打印链表
//非头结点前插入data
InsertNotHead(Find(pHead, 6), 8);
PrintLinkList(pHead);//正向打印链表
/*单链表的逆置——前后指针(定义三个指针)*/
p3=ReverseLinkList1(pHead);
PrintLinkList(p3);//正向打印链表(但是此处传的不是头指针,而是逆置函数的返回值)
//单链表的逆置——头插法
p4=ReverseLinkList(pHead);
PrintLinkList(p4);//正向打印链表(但是此处传的不是头指针,而是逆置函数的返回值)
////查找链表的中间节点--要求不能遍历单链表
p2=FindMidNode(pHead);
printf("%d\n", p2->data);
}
int main()
{
test();
system("pause");
return 0;
}