C语言实现单链表的基本操作

ListNode.h

#ifndef __LISTNODE_H__
#define __LISTNODE_H__

#include "stdio.h"
#include "assert.h"
#include "stdlib.h"

typedef int DataType;
typedef unsigned int size_t;

typedef struct Node
{
    DataType _data;
    struct Node* _pNext;
}Node,*PNode;

// 初始化单链表
void InitList(PNode* pHead);
//尾插
void PushBack(PNode* pHead, DataType data);
// 尾删
void PopBack(PNode* pHead);
// 头插
void PushFront(PNode* pHead, DataType data);
// 头删
void PopFront(PNode* pHead);
// 在单链表中查找值为data的结点,找到了返回该结点的地址,否则返回NULL
Node* Find(PNode pHead, DataType data);
// 在单链表pos位置后插入值为data的结点
void Insert(PNode pos, DataType data);
// 在单链表中删除位置为pos的结点
void Erase(PNode* pHead, PNode pos);
// 移除单链表中第一个值为data的结点
void Remove(PNode* pHead, DataType data);
// 移除单链表中所有值为data的结点
void RemoveAll(PNode* pHead, DataType data)
// 获取单链表总结点的总个数
size_t Size(PNode pHead);
// 判断结点是否为空
int Empty(PNode pHead);
// 返回单链表的最后一个结点的位置
PNode Back(PNode pHead);
// 返回单链表的第一个结点的位置
PNode Front(PNode pHead);
// 构建一个新节点
Node* BuyNode(DataType data);
// 正向打印单链表
void PrintList(PNode pHead);
//销毁链表  
void DestroyList(PNode *pHead);

#endif

ListNode.c

#include "ListNode.h"

// 初始化单链表
void InitList(PNode* pHead)
{
    assert(pHead);
    *pHead = NULL;
}

//尾插
void PushBack(PNode* pHead, DataType data)
{
    assert(pHead);
    if(*pHead == NULL)
        *pHead = BuyNode(data);
    else
    {
        Node* pTailNode = *pHead;
        while(pTailNode->_pNext)
            pTailNode = pTailNode->_pNext ;
        pTailNode->_pNext = BuyNode(data);
    }
}

// 尾删
void PopBack(PNode* pHead)
{
    assert(pHead);
    if(NULL == *pHead)
        return ;
    else if(NULL == (*pHead)->_pNext)
    {
        free(*pHead);
        (*pHead)->_pNext = NULL;
    }
    else
    {
        Node *pNode = *pHead;
        while(pNode->_pNext->_pNext)
        {
            pNode = pNode->_pNext ;
        }
        free(pNode->_pNext );
        pNode->_pNext = NULL;
    }
}

// 头插
void PushFront(PNode* pHead, DataType data)
{
    Node *pNew = NULL;
    assert(pHead);
    pNew = BuyNode(data);
    pNew->_pNext = *pHead;
    *pHead = pNew;

}

// 头删
void PopFront(PNode* pHead)
{
    assert(pHead);
    if(NULL == pHead)
        return ;
    else if(NULL == (*pHead)->_pNext)
    {
        free(*pHead);
        (*pHead)->_pNext = NULL;
    }
    else
    {
        Node *pNew = *pHead;
        *pHead = (*pHead)->_pNext ;
        free(pNew);
    }

}

// 在单链表中查找值为data的结点,找到了返回该结点的地址,否则返回NULL
Node* Find(PNode pHead, DataType data)
{
    Node *pCurNode = NULL;
    assert(pHead);
    if(NULL == pHead)
        return NULL;
    pCurNode = pHead;
    while((pCurNode != NULL)&&(pCurNode->_data != data))
        pCurNode = pCurNode->_pNext ;
    return pCurNode;
}

// 在单链表pos位置后插入值为data的结点
void Insert(PNode pos, DataType data)
{
    Node *pNewNode = NULL;
    assert(pos);

    if(!(pNewNode = BuyNode(data)))
        return ;
    pNewNode->_pNext = pos->_pNext ;
    pos->_pNext = pNewNode;
} 

// 在单链表中删除位置为pos的结点
void Erase(PNode* pHead,PNode pos)
{
    Node *pPreNode = NULL;
    assert(pHead);
    assert(pos);

    if(NULL == *pHead)//链表为空时
        return ;
    else if(pos == *pHead)//链表的第一个节点就为pos
        PopFront(pHead);
    else//pos不在头位置
    {
        pPreNode = *pHead;
        while(pPreNode && pPreNode->_pNext != pos)
            pPreNode = pPreNode->_pNext ;
        if(NULL != pPreNode)
        {
            pPreNode->_pNext = pos->_pNext ;
            free(pos);
            pos->_pNext = NULL;
        }
    }
}

// 移除单链表中第一个值为data的结点
void Remove(PNode* pHead, DataType data)
{
    Node *pDelNode = NULL;
    assert(pHead);
    if(NULL == *pHead)
        return ;
    else 
    {
        pDelNode = Find(*pHead,data);
        Erase(pHead,pDelNode);
    }
}

// 移除单链表中所有值为data的结点
void RemoveAll(PNode* pHead, DataType data)  
{  
    PNode pDelNode = NULL;  
    assert(NULL != pHead);  
    pDelNode = *pHead;  

    if (NULL == *pHead)     //链表为空  
        return ;  

    if (NULL == (*pHead)->_pNext) //链表只有一个节点  
    {  
        if ((*pHead)->_data == data)  
            PopFront(pHead);  
    }  
    else  
    {    
        while (pDelNode->_pNext )  
            if (pDelNode->_data == data)  
            {  
                PNode pTemp = pDelNode->_pNext;  

                pDelNode->_data = pTemp->_data;  
                pDelNode->_pNext = pTemp->_pNext;  

                free(pTemp);  
                pTemp = NULL;  
            }  
            else  
                pDelNode = pDelNode->_pNext;  
    }  
} 

// 返回单链表的第一个结点的位置
PNode Front(PNode pHead)
{
    assert(pHead);
    if(NULL == pHead)
        return NULL;
    else
    {
        Node *pFrontNode = pHead;
        return pFrontNode;
    }
}

// 返回单链表的最后一个结点的位置
PNode Back(PNode pHead)
{
    assert(pHead);
    if(NULL == pHead)
        return NULL;
    else
    {
        Node *pBackNode = pHead;
        while(pBackNode->_pNext )
            pBackNode = pBackNode->_pNext ;
        return pBackNode;
    }
}

// 获取单链表总结点的总个数
size_t Size(PNode pHead)
{
    unsigned int count = 0;
    assert(pHead);

    while(pHead)
    {
        pHead = pHead->_pNext ;
        count++;
    }
    return count;
}

// 判断结点是否为空
int Empty(PNode pHead)
{
    assert(pHead);
    if(NULL != pHead)
        return 0;//不为空
    return 1;//为空
}

// 正向打印单链表
void PrintList(PNode pHead)
{
    Node* pNode = pHead;
    assert(pHead);
    while(pNode)
    {
        printf("%d->",pNode->_data );
        pNode = pNode->_pNext ;
    }
    printf("\n");
}

// 构建一个新节点
Node* BuyNode(DataType data)
{
    Node *pNewNode = (Node*)malloc(sizeof(Node));

    if(pNewNode != NULL)
    {
        pNewNode->_data = data;
        pNewNode->_pNext = NULL;
    }
    return pNewNode;
}

//销毁链表  
void DestroyList(PNode *pHead)  
{  
    PNode pCurNode = NULL;  

    assert(pHead);  

    while (NULL != *pHead)  
    {  
        PNode pTemp = *pHead;  
        *pHead = (*pHead)->_pNext;  
        free(pTemp);  
        pTemp = NULL;  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值