天天看點

連結清單内容的補充2:靜态連結清單

1.基本結構

連結清單的一般定義是n個節點通過指針互相連接配接形成連結清單。靜态連結清單是借由一維數組對于線性連結清單進行描述,靜态連結清單的資料域仍然記作變量data,不同于一般的線性連結清單,其“指針”用一個int 類型的變量cur來表示,而不是傳回類型為Node的指針next。靜态連結清單單個元素的類型名稱記作component,類似地,指針域用一個Slinklist數組來表示,通路位序為i的元素的指針需要定義slinklist類型的對象space,通過space[i].cur完成對指針的指派。靜态連結清單的基本結構代碼如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct
{
    int data;
    int cur;
}component,slinklist[1000];
           

靜态連結清單中的元素位序下标與元素指針需要分别看待,定義一個slinklist型的變量記作space,space[i].cur訓示了第i個元素在靜态連結清單中的位置,而假設int 型變量j=space[i].cur,則s[j].data存儲了線性表的第i位元素的資料。根據以上的性質,可以實作在靜态連結清單中的定位函數,基本思路如下:  1)定義變量i,初始化為靜态連結清單中第0個元素的位置     2)通過while循環,利用判斷條件,當space[i]的資料域不為e時,将i指派為space[i].cur ,即通過變量cur的值,通路位序為i的元素的後繼結點  3)循環直到資料域等于e為止  代碼如下:

int locate(slinklist space,int e)
{
    int i=space[0].cur;
    while(i&&space[i].data!=e)
    {
        i=space[i].cur;
    }
    return i;
}
           

2.靜态連結清單的連結清單初始化函數以及結點初始化函數

實作了靜态連結清單的定位函數後,可以實作靜态連結清單的插入以及删除算法,靜态連結清單的插入以及删除操作不需要移動元素,隻需要修改指針域的值即可完成元素的移動。插入操作需要自行定義兩個函數,包括靜态連結清單的連結清單初始化函數Init(Slinklist space),以及靜态連結清單節點的初始化函數malloc(Slinklist space).靜态連結清單的連結清單初始化函數主要思路如下:1)建立一個Slinklist類型的數組space,用于表示結點的資料域以及指針域   2)通過for循環,初始化space數組的指針域,space[0]的指針域記作1,即靜态連結清單space的位序為1的元素後繼是位序為2的元素,以此類推,直到space[max-1]的指針域為0,即靜态連結清單space的最後一個元素的後繼元素是靜态連結清單的位序為1的元素,達成了一個連結清單的循環,代碼如下:

void Init(slinklist space)
{
   for(int i=0;i<max-1;i++)
  {
     space[i].cur=i+1;
  }
     space[max-1].cur=0;
}
           

靜态連結清單節點的初始化函數主要思路如下:1)定義一個變量i作為位序為1的元素的後繼,語句為:int i=space[0].cur   2)進行條件的判斷,如果此時位序為1的元素後繼位序不為0時(後繼為0表示位序為1的元素後繼與表尾元素相同,同時意味着連結清單已滿) space[0].cur=space[i].cur;相當于是有結點插入在位序為1的元素之前,同時該結點的位序由位序為1的元素獲得。在應用之中,由于space[0].cur初始化為1,是以i一般由1開始變化。每插入一個新節點,space[0].cur的值會更新。在靜态連結清單的插入操作中,該函數用于獲得靜态連結清單邏輯位序為2的結點的實體位序。代碼以及示意圖如下:

int malloc(slinklist space)
{
    int i=space[0].cur;
    if(space[0].cur)
    {
       space[0].cur=space[i].cur;
    }
   return i;
}
           
連結清單内容的補充2:靜态連結清單

靜态連結清單初始化

連結清單内容的補充2:靜态連結清單

靜态連結清單中位序為2的結點初始化

3.靜态連結清單的插入函數 

靜态連結清單的初始化插入操作函數基本思路如下:1)假定函數的參數為space數組,要求在靜态連結清單的第m+1位之前插入(位序為m+1,同時m由0開始增加至Max-1) ,待插入的結點資料值為e   2)定義變量j,k,l   變量j初始化為位序為1的結點的後繼結點(j=malloc(space)),變量k初始化為max-1,用于在for循環中尋找第m+1個結點的位序(k=space[max-1].cur,初始值為1,經過m-1次循環可以找到結點位置)  3)将新插入的結點的後繼結點設定為與此時的第m個結點相同,第m個結點的後繼設定為新插入的結點j(此處與單連結清單插入節點的方法相同)。代碼如下:

void Insert(slinklist space,int e,int m)
    {
        int k=max-1;
        int j=malloc(space);
        space[j].data=e;
        for(int i=1;i<=m-1;i++)
        {
            k=space[k].cur;
        }
        space[j].cur=space[k].cur;
        space[k].cur=j;
    }
           

4.靜态連結清單的周遊操作

靜态連結清單的周遊函數主要的思路為:1)在插入了n個結點後,定義一個變量為k,k初始化為space[max-1].cur,即初始化為實體位序最大的結點的後繼   2)進行while循環,當結點i的後繼不為0(後繼為0意味着結束連結清單的輸出,位序為0的結點資料值為空且其後繼的所有節點資料值均為空),輸出實體位序為i的結點的數值以及使i通路其邏輯位序的後繼。

void travel(slinklist space)
    {
        int i=space[max-1].cur;
        while(space[i].cur!=0)
        {
            cout<<i<<" "<<space[i].data<<" "<<space[i].cur<<endl;
            i=space[i].cur;
        }
    }
           
連結清單内容的補充2:靜态連結清單

靜态連結清單初始化

連結清單内容的補充2:靜态連結清單

靜态連結清單完成元素插入示意圖

靜态連結清單插入元素,周遊元素的主程式代碼如下:

int main()
    {
        slinklist space;
        Init(space);
        int m;
        cin>>m;
        int num[m];
        for(int i=0;i<m;i++)
        {
            cin>>num[i];
        }
        for(int k=0;k<=m;k++)
        {
            Insert(space,num[k],k+1);
        }
        travel(space);
        return 0;
    }
           

 5.靜态連結清單的釋放空間操作以及删除結點

靜态連結清單的删除操作,與靜态連結清單的插入操作類似的,僅僅隻需通過修改指針域來完成元素的“删除”,在定義删除操作前,前行定義釋放邏輯位序為k+1的結點的函數free(slinklist space,k),釋放結點空間的操作等同于将邏輯位序為k+1的結點的後繼設定為實體位序為1的元素的後繼,再将實體位序為1的元素後繼設定為這個釋放的結點,相當于将該節點連結入一個無用的連結清單之中(屬于實體位序為1的結點的後繼,無法被通路到)。具體代碼如下:

int free(slinklist space,int k)
    {
        space[k].cur=space[0].cur;
        space[0].cur=k;
    }
           

類比單連結清單的形式,在定義完成free函數後,進行删除操作的基本思路如下:1)定義變量i,表示删除邏輯位序為i的元素 2)定義變量k,m,l 。變量k用于通路邏輯位序為i-1,i,i+1的元素,先通過for循環通路邏輯位序為i-1的元素,用變量m存儲其實體位序,此處用 m=space[k].cur語句進行表示   3)進行兩次通路後繼節點操作後,用變量l存儲該節點的實體位序    4)将m的後繼結點值賦為l,就達到了删除結點k的目的   4)釋放此時位序為k的結點的空間(在通路位序為i-1的元素後進行的第一次通路後繼結點語句将k的值賦成i,此處的i與k是等價的)   5) 定義int類型變量e,使用e傳回删除的元素值    。代碼如下所示:

void Delete(slinklist space,int i)
    {
        int k=max-1;
        int l,m;
        for(int j=0;j<=i-2;j++)
        {
            k=space[k].cur;
        }
        m=k;
        k=space[m].cur;
        l=space[k].cur;
        space[m].cur=l;
        int e=space[k].data;
        cout<<e<<endl;
        free(space,k);
    }
           

繼續閱讀