鏈表操作常見技巧淺析

鏈表操作是程序設計中最常見的一類操作。在我們項目或面試中經常會用到,我們可以大致總結下鏈表操作的常見技巧。其實也沒有什麼難點,主要是操作列表時,注意異常邊界值的考慮。一般在修改鏈表時,會用到輔助鏈表指針,其目的在我看來主要有2個作用:一是將當前結點保存起來,好讓此時結點的指針指向下一結點(這裏可以類似看做一個遊標,向前或向後的結點移動。二是利用輔助鏈表指針的位置來實現特定的目的)。我們主要看到這裏數據域則爲該結點保存的值,而指針域可以看作一個遊標,通過它來指向下一個結點(pList->next),也可以指向下一個結點的結點(pList->next->next),。。。。。。這樣就可以遍歷整個鏈表了。


下面是某一類常見的鏈表操作,代碼都比較簡練,熟悉了操作步驟,寫這些代碼應該是不難的!

#include <stdio.h>

#include <string.h>
#include <stdlib.h>

struct ListNode
{
    int data;    //---------------數據域
    ListNode *next; //--------------指針域
};

unsigned int getListLength(ListNode *pList)
{
    if (pList == NULL)
    {
        return 0;
    }
    unsigned len = 0;
    ListNode *pCur = pList;
    while (pCur != NULL)
    {
        len++;
        pCur = pCur->next;
    }

    return len;
}

ListNode *createList(int n)
{
    if (n <= 0)
    {
        return NULL;
    }
    ListNode *pCurrent = NULL;
    ListNode *pHead = NULL;
    for(int i = 0; i < n; i++)
    {
        pCurrent = (ListNode*)malloc(sizeof(struct ListNode));
        pCurrent->data = i + 1;
        pCurrent->next = pHead;
        pHead = pCurrent;
    }

    return pHead;

}

void traverseList(ListNode *pList) //遍歷鏈表
{
    while (pList != NULL)
    {
        printf("%d\n", pList->data);
        pList = pList->next;
    }
}

void freeList(ListNode *pList)
{
    while(pList != NULL)
    {
        ListNode *pTemp = pList;
        pList = pList->next;
        free(pTemp);
    }
}


ListNode *reverseList(ListNode *pList)
{
    if (pList == NULL || pList->next == NULL)
    {
        return pList;
    }
    ListNode *pHead = NULL;
    ListNode *pCur = pList;
    while (pCur != NULL)
    {
        ListNode *pTemp = pCur;
        pCur = pCur->next;
        pTemp->next = pHead;
        pHead = pTemp;
    }
    return pHead;
}


ListNode *getRightKthNode(ListNode *pList, int k)
{
    if (k <=0 || pList == NULL)
    {
        return NULL;
    }

    ListNode *pAhead = pList;
    ListNode *pBehind = pList;
    while (k > 1 && pAhead != NULL)
    {
        pAhead = pAhead->next;
        k--;
    }
    if (k > 1 || pAhead == NULL)
    {
        return NULL;
    }

    while (pAhead->next != NULL)
    {
        pBehind = pBehind->next;
        pAhead = pAhead->next;
    }

    return pBehind;

}

ListNode *getMiddleNode(ListNode *pList)
{
    if (pList == NULL || pList->next == NULL)
    {
        return pList;
    }
    ListNode *pAhead = pList;
    ListNode *pBehind = pList;
    while (pAhead->next != NULL)
    {
        pBehind = pBehind->next;
        pAhead = pAhead->next;
        if (pAhead->next != NULL)
        {
            pAhead = pAhead->next;
        }
    }
    return pBehind;
}

void reversePrintList(const ListNode *pList)
{
    if (pList == NULL)
    {
        return;
    }
    else
    {
       reversePrintList(pList->next);
       printf("%d\n", pList->data);
    }


}

void reversePrintStr(const char *str)
{
    if(*str == '\0')
    {
        return;
    }
    else
    {
        reversePrintStr(str+1);
        printf("%c", *str);
    }


}


int main()

{
    ListNode *pList = NULL;
    pList = createList(10);
    printf("********reversePrintList***********\n");
    reversePrintList(pList);
    printf("********getListLength***********\n");
    printf("%d\n", getListLength(pList));
    printf("********traverseList***********\n");
    traverseList(pList);
    printf("********reverseList***********\n");
    pList = reverseList(pList);
    traverseList(pList);
    printf("*********getRightKthNode**********\n");
    ListNode *pHead = getRightKthNode(pList, 6);
    printf("%d\n", pHead->data);
    printf("********getMiddleNode***********\n");
    pHead = getMiddleNode(pList);
    printf("%d\n", pHead->data);



    freeList(pList);


    reversePrintStr("abcde");

    return 0;

}

打印結果如下:



====================補充==========================================

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct node
{
    int data; //數據域
    struct node *next; //指針域
} SList;

SList * createList(int n) //創建單鏈表
{
    SList *pHead = NULL;
    for (int i = 0; i < n; i++)
    {
        SList *pNode = (SList*)malloc(sizeof(SList));
        pNode->data = i + 1;
        pNode->next = pHead;
        pHead = pNode;
    }

    return pHead;
}

void printList(SList *pList) //遍歷單鏈表
{
    while(pList != NULL)
    {
        fprintf(stdout, "%d\n", pList->data);
        pList = pList->next;
    }
    printf("******************\n");
}

SList *addNodeToTail(SList *pList, int data) //結點加入鏈表尾
{
    SList *pHead = pList;

    SList *pNode = (SList*)malloc(sizeof(SList));
    pNode->data = data;
    pNode->next = NULL;

    if(pHead == NULL)
    {
        pHead = pNode;
        return pHead;
    }

    while (pHead->next != NULL)
    {
        pHead = pHead->next;
    }

    pHead->next = pNode;

    return pList;
}


SList *deleteNode(SList *pList, int data) //刪除指定元素的值
{
    if (pList == NULL)
    {
        return pList;
    }

    SList *pHead = pList;
    SList *preHead = NULL;

    while(pHead != NULL)
    {
        if (pHead->data == data)
        {
            SList *deNode = pHead;
            pHead = pHead->next;
            if (NULL != preHead)
            {
                preHead->next = pHead;
            }
            else
            {
                pList = pHead;
            }
            free(deNode);
        }
        else
        {
            preHead = pHead;
            pHead = pHead->next;
        }
    }
    return pList;
}




int main()
{
    SList *pList = createList(5);
    printList(pList);

    pList = deleteNode(pList, 5);
    printList(pList);

    pList = addNodeToTail(pList, 1);
    printList(pList);

    pList = deleteNode(pList, 1);
    printList(pList);
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章