单链表的基本算法2---C语言实现

LinkList.h

#ifndef __LINK_LIST_H__
#define __LINK_LIST_H__
#include
#include
#include
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;
}

你可能感兴趣的:(数据结构)