1. 程式人生 > >數據結構 -- 鏈表&雙向鏈表

數據結構 -- 鏈表&雙向鏈表

ted bsp scan 添加 play rev 數組 prev 指向

鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。


使用鏈表結構可以克服數組鏈表需要預先知道數據大小的缺點,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。但是鏈表失去了數組隨機讀取的優點,同時鏈表由於增加了結點的指針域,空間開銷比較大。鏈表最明顯的好處就是,常規數組排列關聯項目的方式可能不同於這些數據項目在記憶體或磁盤上順序,數據的存取往往要在不同的排列順序中轉換。鏈表允許插入和移除表上任意位置上的節點,但是不允許隨機存取。鏈表有很多種不同的類型:單向鏈表,雙向鏈表以及循環鏈表等。


相較之於單鏈表,雙向鏈表在查找前驅節點時更為方便,而單向鏈表卻需要遍歷查找;而相較之於雙向鏈表,單鏈表在更加節省內存空間(雙向鏈表比單鏈表多定義了一個指向前驅結點的指針)。


以下為關於單鏈表以及雙向鏈表的c++實現方法:


1. 單鏈表



#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

typedef struct linkTable{
    int info;
    linkTable *next;
};

//創建鏈表

linkTable* createLinkTable(linkTable *node)
{
    int temp = 0;
    linkTable *head = NULL;
    linkTable *p = (linkTable*)malloc(sizeof(linkTable));
    while (1)
    {
        scanf("%d",&temp);
        if (temp != -9999)
        {
            if (head == NULL)
            {
                p->info = temp;
                p->next = NULL;
                head = p;
            }else{
                linkTable *newnode = (linkTable *)malloc(sizeof(linkTable));
                newnode->info = temp;
                newnode->next = NULL;
                p->next = newnode;
                p = p->next;
            }
        }else{
            break;
        }
    }
    return head;

}

//在鏈表頭部插入節點

linkTable* insertToHead(linkTable *node , int val)
{
    linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    scanf("%d",newnode->info);
    newnode->next = node;
    return newnode;
}

//在鏈表中間插入節點

void insertToMid(linkTable *node , int val , int pos)
{
    int count = 0;
    linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    newnode->info = val;
    while (node->next != NULL && ++count < pos-1)
    {
        node = node->next;
    }
    newnode->next = node->next;
    node->next = newnode;
    return;
}

//插入尾部節點

void insertToTail(linkTable *node , int val)
{
    linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    newnode->info = val;
    newnode->next = NULL;
    while (node->next != 0)
    {
        node = node->next;
    }
    node->next = newnode;
    return;
}

//顯示所有節點數值

void display(linkTable *node)
{
    while (node != NULL)
    {
        printf("%d ",node->info);
        node = node->next;
    }
    return;
}

//刪除起始節點

linkTable* deleteHead(linkTable *node)
{
    linkTable *tempNode = (linkTable*)malloc(sizeof(linkTable));
    tempNode = node;
    node = node->next;
    free(tempNode);
    return node;
}

//刪除尾部節點

void deleteTail(linkTable *node)
{
    linkTable *tempNode = (linkTable*)malloc(sizeof(linkTable));
    while (node->next->next != NULL && node->next != NULL)
    {
        node = node->next;
    }
    tempNode = node->next;
    node->next = NULL;
    free(tempNode);
    return;
}

//搜索指定節點,並返回節點

linkTable* searchNode(linkTable *node , int val)
{
    while (node->info != val)
    {
        if (node == NULL)
        {
            printf("No element ! \n");
            return NULL;
        }
        node = node->next;
    }
    return node;
}

int main(void)
{
    linkTable *node = (linkTable*)malloc(sizeof(linkTable));
    node = createLinkTable(node);
    display(node);
    return 0;
}



2. 雙向鏈表

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>

using namespace std;

typedef struct DLinkList{
    int info;
    DLinkList *prev;
    DLinkList *next;
};

//鏈表的創建

DLinkList* createDLT(void)
{
    int temp = 0;
    DLinkList *p = (DLinkList*)malloc(sizeof(DLinkList));
    DLinkList *head = NULL;
    while (1)
    {
        scanf("%d",&temp);
        if (temp != -9999)
        {
            if (head == NULL)
            {
                head = (DLinkList*)malloc(sizeof(DLinkList));
                p->info = temp;
                p->next = NULL;
                p->prev = NULL;
                head = p;
            }else{
                DLinkList *newnode = (DLinkList*)malloc(sizeof(DLinkList));
                newnode->info = temp;
                newnode->prev = p;
                newnode->next = NULL;
                p->next = newnode;
                p = p->next;
            }
        }else{
            break;
        }
    }
    return head;
}

//鏈表的遍歷輸出

void display(DLinkList *node)
{
    while (node != NULL)
    {
        printf("%d  ",node->info);
        node = node->next;
    }
    return;
}

//添加鏈表頭節點

DLinkList* insert_Head(DLinkList *node , int val)
{
    DLinkList *newnode = (DLinkList*)malloc(sizeof(DLinkList));
    newnode->info = val;
    newnode->next = node;
    newnode->prev = NULL;
    node->prev = newnode;
    return newnode;
}

//刪除鏈表某位置元素

void delete_Elem(DLinkList *node , int n)
{
    int count = 1;
    while (count < n && node != NULL)
    {
        node = node->next;
        count++;
    }
    if (node != NULL)
    {
        if (node->next != NULL)
        {
            node->prev->next = node->next;
            node->next->prev = node->prev;
        }else{
            node->prev->next = NULL;
        }
    }
    return;
}

int main(void)
{
    DLinkList *node = (DLinkList*)malloc(sizeof(DLinkList));
    node = createDLT();
    node = insert_Head(node,9);
    delete_Elem(node,2);
    display(node);
    return 0;
}

數據結構 -- 鏈表&雙向鏈表