鏈表的基本操作

/*
C++學習筆記02——鏈表的基本操作
2017.03.25
*/

#define _CRT_SECURE_NO_WARNINGS
#include "stdlib.h"
#include "stdio.h"
#include "string.h"

typedef struct Node
{
    int data;
    struct Node *next;
}SLIST;

SLIST *Creat_SList();
int SList_Print(SLIST *pHead);
//在結點數值爲x的前面插入y
int SList_NodeInsert(SLIST *pHead, int x, int y);
//刪除結點爲y的鏈表結點
int SList_NodeDel(SLIST *pHead, int y);
int SList_Destory(SLIST *pHead);
int SList_revse(SLIST *pHead);

SLIST *Creat_SList()
{
    //1 創建頭結點並初始化 
    int data = 0;
    SLIST *pHead = NULL, *pM = NULL, *pCur;
    pHead = (SLIST *)malloc(sizeof(SLIST));
    if (pHead == NULL)
    {
        return NULL;
    }
    pHead->data = 0;
    pHead->next = NULL;

    //2循環創建結點,結點數據域中的數值從鍵盤輸入,
    //以-1作爲輸入結束標誌
    printf("\nPlease enter the data of node(-1:quit) ");
    scanf("%d", &data);

    //準備環境 讓pCur指向pHead
    pCur = pHead;
    while (data != -1)
    {
        //不斷的malloc新節點 並且數據域 賦值
        pM = (SLIST *)malloc(sizeof(SLIST));
        if (pM == NULL)
        {
            SList_Destory(pHead);
            return NULL;
        }
        pM->data = data;
        pM->next = NULL;

        //1新節點入鏈表
        pCur->next = pM;

        //2 當前結點下移(新結點變成當前結點)
        pCur = pM; // (pCur = pCur->next)

        printf("\nPlease enter the data of node(-1:quit) ");
        scanf("%d", &data);
    }
    return pHead;
}


int Creat_SList2(SLIST **Head)
{
    int ret = 0;
    //1 創建頭結點並初始化 
    int data = 0;
    SLIST *pHead = NULL, *pM = NULL, *pCur = NULL;
    pHead = (SLIST *)malloc(sizeof(SLIST));
    if (pHead == NULL)
    {
        ret = -1;
        printf("func Creat_SList() err:%d", ret);
        return ret;
    }
    pHead->data = 0;
    pHead->next = NULL;

    //2循環創建結點,結點數據域中的數值從鍵盤輸入,
    //以-1作爲輸入結束標誌
    printf("\nPlease enter the data of node(-1:quit) ");
    scanf("%d", &data);

    //準備環境 讓pCur指向pHead
    pCur = pHead;
    while (data != -1)
    {
        //不斷的malloc新節點 並且數據域 賦值
        pM = (SLIST *)malloc(sizeof(SLIST));
        if (pM == NULL)
        {
            SList_Destory(pHead);
            ret = -2;
            printf("func Creat_SList() err:%d malloc err", ret);
            return ret;
        }
        pM->data = data;
        pM->next = NULL;

        //1新節點入鏈表
        pCur->next = pM;

        //2 當前結點下移(新結點變成當前結點)
        pCur = pM; // (pCur = pCur->next)

        printf("\nPlease enter the data of node(-1:quit) ");
        scanf("%d", &data);
    }
    *Head = pHead;
    return ret;
}

int SList_Print(SLIST *pHead)
{
    SLIST *p = NULL;

    if (pHead == NULL)
    {
        return -1;
    }
    //準備環境
    p = pHead->next;
    printf("\nBegin ");
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("End ");
    return 0;
}

//在結點數值爲x的前面插入y
int SList_NodeInsert(SLIST *pHead, int x, int y)
{
    SLIST *pCur = NULL, *pPre = NULL, *pM = NULL;
    if (pHead == NULL)
    {
        return -1;
    }
    //環境準備
    pPre = pHead;
    pCur = pHead->next;

    //不斷的malloc新節點 並且數據域 賦值
    pM = (SLIST *)malloc(sizeof(SLIST));
    pM->data = y;
    pM->next = NULL;

    while (pCur)
    {
        if (pCur->data == x)
        {
            break;
        }
        //讓pPre下移
        pPre = pCur;
        //讓當前節點下移
        pCur = pCur->next;
    }

    //讓新節點鏈接後繼結點
    pM->next = pPre->next; //(pCur)
    //讓前驅結點連接pM
    pPre->next = pM;

    return 0;
}

//刪除結點爲y的鏈表結點
int SList_NodeDel(SLIST *pHead, int y)
{
    SLIST *pCur = NULL, *pPre = NULL;
    if (pHead == NULL)
    {
        return -1;
    }
    //環境準備
    pPre = pHead;
    pCur = pHead->next;

    while (pCur)
    {
        if (pCur->data == y)
        {
            break;
        }
        //讓pPre下移
        pPre = pCur;
        //讓當前節點下移
        pCur = pCur->next;
    }
    if (pCur == NULL)
    {
        printf("沒有找到節點 y:%d", y);
        return -2;
    }
    //執行操作
    pPre->next = pCur->next;
    free(pCur);
    return 0;
}


int SList_Destory(SLIST *pHead)
{
    //1、刪除當前結點前,需要把後繼結點位置緩存

    SLIST *pTmp = NULL;
    SLIST *pCur = pHead;
    if (pHead == NULL)
    {
        return -1;
    }

    while (pCur)
    {
        //緩存後繼結點位置
        pTmp = pCur->next;
        //刪除當前結點
        free(pCur);
        //當前結點下移
        pCur = pTmp;
    }
    return 0;
}

int SList_revse(SLIST *pHead)
{

    SLIST *p = NULL, *q = NULL, *t = NULL;

    if (pHead == NULL)
    {
        return -1;
    }
    if (pHead->next == NULL || pHead->next->next == NULL)
    {
        return 0;
    }
    //準備環境
    p = pHead->next;
    q = pHead->next->next;

    while (q != NULL)
    {
        //1、在逆置之前需要做一個緩存
        t = q->next;

        //2、開始逆置
        q->next = p;

        //3、讓p後移
        p = q;
        //4、q後移
        q = t;
    }

    //讓第一個業務結點賦值null
    pHead->next->next = NULL;
    //讓鏈表頭指向最後一個節點
    pHead->next = p;
    return 0;
}


void main()
{
    int ret = 0;
    SLIST *pHead = NULL;
    //創建 並打印 
    pHead = Creat_SList();
    ret = SList_Print(pHead);

    //插入操作
    ret = SList_NodeInsert(pHead, 20, 19);
    ret = SList_Print(pHead);

    ret = SList_NodeDel(pHead, 19);
    ret = SList_Print(pHead);

    ret = SList_revse(pHead);
    ret = SList_Print(pHead);

    ret = SList_Destory(pHead);
    system("pause");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章