带头结点单链表

带头结点的单链表(无循坏)


#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <assert.h>
#include <malloc.h>
#pragma warning <disable:4996>

//////////////////////////////////////////////////////
typedef int DataType;

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

void SListInit(PNode* ppHead);//初始化//二级指针
PNode TouchSListNode(DataType data);//创建节点
void SListPrint(PNode pHead);//打印链表
void PrintSListFromTail(PNode pHead); //递归逆序打印链表
void SListPushFront(PNode* ppHead, DataType data); //头插
void SListPopFront(PNode* ppHead);//头删
void SListPushBack(PNode* ppHead, DataType data);//尾插
void SListPopBack(PNode* ppHead);//尾删
void SListInsert(PNode *ppHead, PNode pos, DataType data);//任意位置插入//将data插入pos之前的位置
void SListErase(PNode *ppHead, PNode pos);//任意位置的删除
PNode FindPos(PNode pHead, DataType data);//找到第一个值为data的节点

//////////////////////////////////////////////////////
void SListInit(PNode* ppHead)//初始化//二级指针
{
    assert(ppHead);
    *ppHead = NULL;
}

void SListPrint(PNode pHead)//打印链表
{
    PNode pCur = pHead;
    while (pCur)
    {
        printf("%d --> ", pCur->_data);
        pCur = pCur->_pNext;
    }
    printf("NULL\n");
}

//时间复杂度 O(n)  空间复杂度 O(n)
void PrintSListFromTail(PNode pHead) //递归逆序打印链表
{ 
    if (pHead)//递归出口
    {
        PrintSListFromTail(pHead->_pNext);
        printf(" <-- %d", pHead->_data);
    }
}


PNode TouchSListNode(DataType data)//创建节点
{
    PNode pNewNode = (PNode)malloc(sizeof(Node));
    assert(pNewNode);
    pNewNode->_data = data;
    pNewNode->_pNext = NULL;
    return pNewNode;
}

void SListPushFront(PNode* ppHead, DataType data) //头插
{
    PNode pNewNode = TouchSListNode(data);
    pNewNode->_pNext = *ppHead;
    *ppHead = pNewNode;
}

void SListPopFront(PNode* ppHead)//头删
{
    assert(ppHead);
    PNode pNewNode = *ppHead;
    if (NULL == *ppHead)
        return;
    *ppHead = pNewNode->_pNext;
    free(pNewNode);
}

void SListPushBack(PNode* ppHead, DataType data)//尾插
{
    assert(ppHead);//是否存在
    if (NULL == *ppHead)//空链表
    {
        *ppHead = TouchSListNode(data);
    }
    else //普通链表
    {
        PNode pTail = *ppHead;
        while (pTail->_pNext) 
        {
            pTail = pTail->_pNext;
        }
        pTail->_pNext = TouchSListNode(data);
    }

}

void SListPopBack(PNode* ppHead)//尾删
{
    assert(ppHead);//存在与否
    if (NULL == *ppHead)//判空
        return;
    else if (NULL == (*ppHead)->_pNext)//链表只有一个结点
    {
        free(*ppHead);
        *ppHead = NULL;
    }
    else//多个节点
    {
        PNode pTail = *ppHead;
        PNode tmp = NULL;
        while (pTail->_pNext)//直到找到一个节点的_pNext为0
        {
            tmp = pTail;
            pTail = pTail->_pNext;
        }
        free(pTail);
        tmp->_pNext = NULL;
    }
}

void SListInsert(PNode *ppHead, PNode pos, DataType data) //任意位置插入//将data插入pos之前的位置
{
    assert(ppHead);
    PNode pNewNode = TouchSListNode(data);
    if (NULL == *ppHead || NULL == pos)
        return;
    else if (pos == *ppHead)
    {
        pNewNode->_pNext = *ppHead;
        *ppHead = pNewNode;
    }
    else
    {
        PNode pCur = *ppHead;
        while (pCur && pCur->_pNext != pos)
        {
            pCur = pCur->_pNext;
        }
        if (pCur)
        {
            pCur->_pNext = pNewNode;
            pNewNode->_pNext = pos;
        }
    }
}

void SListErase(PNode *ppHead, PNode pos)//任意位置的删除
{
    assert(ppHead);
    if (NULL == *ppHead || NULL == pos)
        return;
    if (pos == *ppHead)
    {
        *ppHead = pos->_pNext;
    }
    else 
    {
        PNode pCur = *ppHead;
        while (pCur && pCur->_pNext != pos)
        {
            pCur = pCur->_pNext;
        }
        if (pCur)
        {
            pCur->_pNext = pos->_pNext;
        }
        free(pos);
    }
}


PNode FindPos(PNode pHead, DataType data)//找到第一个值为data的节点
{
    assert(pHead);
    if (NULL == pHead)
        return NULL;
    PNode pCur = pHead;
    while (pCur)
    {
        if (pCur->_data == data)
            return pCur;
        pCur = pCur->_pNext;
    }
    return NULL;
}

void SListDestroy(PNode *ppHead)//正向销毁链表
{
    assert(ppHead);
    PNode pCur = *ppHead;
    PNode pStr = NULL;
    while (pCur)
    {
        pStr = pCur;
        pCur = pCur->_pNext;
        free(pStr);
    }
    *ppHead = NULL;
}

int SListSize(PNode pHead)//链表长度
{
    int count = 0;
    PNode pCur = pHead;
    while (pCur)
    {
        count++;
        pCur = pCur->_pNext;
    }
    return count;
}

void TestSList( )//测试
{
    int len;
    PNode pHead,pCur;
    SListInit(&pHead);//传地址才能改变内部参数
    SListPushFront(&pHead, 1);
    SListPushFront(&pHead, 2);
    SListPushFront(&pHead, 3);
    SListPushFront(&pHead, 4);
    SListPushFront(&pHead, 5);
    //SListPushFront(&pHead, 6);
    //pCur = TouchSListNode(4);
    //SListPopFront(&pHead);
    //SListPushBack(&pHead, 0);
    //SListPopBack(&pHead);
    pCur = FindPos(pHead,2);
    //SListInsert(&pHead, pCur, 9);
    SListErase(&pHead, pCur);
    len = SListSize(pHead);
    printf("%d\n", len);
    SListPrint(pHead);
    //printf("%p\n", &pCur);
    //SListPrint(pCur);
    //PrintSListFromTail(pHead);
}

int main()
{
    TestSList();

    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/romantic_c/article/details/79919836