數據結構與算法分析/C 學習筆記之

確定性跳躍表
?鏈表的定義

??關于表的定義,這里只簡單的闡述一下:表同圖、集合一樣是一種抽象數據類型。值得指出的是,每一種數據類型都有與自己相關的操作,比如數字類型的 取余等。

鏈表的基本結構

        /*結構體指針 *PtrToNode ,然后可以用 PtrToNode xxx來定義一個結構體,相當于 struct Node *xxx; 這里指出一點:
         點操作符左邊的操作數是一個“結果為結構”的表達式;
         箭頭操作符左邊的操作數是一個指向結構的指針。
         PtrToNode保存的是一個首地址,(*Position).Element ,和Position->Element 結果是一樣的;這里寫成struct Node * 類型,個人理解應該是想用 ->操作符讀寫結構體成員,這樣比點操作符;
        */
        typedef struct Node *PtrToNode;  //創建節點數據類型,方便后續代碼使用
        typedef PtrToNode List;  //創建鏈表結構,包含 [值]和[下一個節點的地址]
        typedef PtrToNode Position;  //
        struct Node
        {
            int Element;
            Position Next;
        };



Ⅰ 1-2-3確定性跳躍表

  • 性質: 每一個間隙(除在頭和尾之間可能的零間隙外)的容量為1,2或3;

1-2-3確定性跳躍表的基本結構

??簡析:上圖中有兩個容量為3的間隙:第一個是 25 和 45 之間高度為 1 的的三個元素,第二個是頭尾節點之間高度為2的三個元素。


Ⅱ 代碼實現

  • 實現效果

效果圖

??簡析:結構體設計為初始點為 Top&Right ;每個節點有一個Right指針,一個Down指針;具體細節下面將上代碼分析。



  • 結構體類型
#include <stdio.h>
#include <stdlib.h>

#define Error(str) printf("%s \n",str),exit(1)  // 定義一個遇見錯誤終止操作函數;
#define Infinity (10000)  // 代表圖的無窮大:∞

typedef int ElementType; // 定義int別名為ElementType,方便識記
typedef struct SkipNode *SkipList; //定義struct SkipNode *類型,代碼里是用來創建表頭而已;
typedef struct SkipNode *Position; // 插入操作生成新的結點,主要由Position創建;

struct SkipNode
{
    ElementType Element;
    SkipList Right;
    SkipList Down;
};

static Position Bottom = NULL;  /*需要初始化為空*/
static Position Tail   = NULL;  /* 需要初始化為空*/

??簡析:很顯然,實現如圖的鏈表,一個結構體需要3個變量,分別為保存值的數據變量,一個指向Next結點的指針變量,一個指向Down的指針變量。其中定義的 Tail 用來方便判斷是否當前結點的位置,以方便編程;Bottom 是一個臨時存放數值的結構體,每次插入操作,每次操作會先存放到Bottom里,然后新建結點再轉移數值;



  • 初始化

SkipList Initialize()
{
    SkipList L;

    if(Bottom == NULL )
    {
        // 這里有一個知識點 sizeof(Bottom)=4; sizeof(struct SkipNode)=12; 
        Bottom = malloc( sizeof(struct SkipNode));
        if(Bottom == NULL )
            Error("out of space");
        Bottom->Right = Bottom->Down =  Bottom;

        Tail = malloc( sizeof(struct SkipNode));
        if(Tail == NULL )
            Error("out of space");
        Tail->Element = Infinity ;
        Tail->Right = Tail;
    }

    /*  創建Header節點 */
    L = malloc( sizeof( struct SkipNode ) );
    if( L == NULL )
        Error( "Out of space!!!" );
    L->Element = Infinity;
    L->Right = Tail;
    L->Down = Bottom;

    return L;
}

初始化結構體

??簡析:Bottom->Right ,Bottom->Down ,Tail->Right指向它們自己本身;Tail->Down = NULL; L在程序里始終為Header節點;



  • 插入操作

重點:
while(Item > Current->Element)
if( Current->Element > Current->Down->Right->Right->Element )
?????

SkipList Insert(ElementType Item, SkipList L)
{
    Position Current = L;
    Position NewNode;

    Bottom->Element = Item;
    while( Current != Bottom )
    {
        while(Item > Current->Element )
            Current = Current->Right;
        //下面這句代碼是重點
        if( Current->Element > Current->Down->Right->Right->Element )
        {
            NewNode = malloc( sizeof( struct SkipNode ));

            if(NewNode == NULL )
                Error("out of space ");

            NewNode->Right = Current->Right;
            NewNode->Down = Current->Down->Right->Right;
            Current->Right = NewNode;
            NewNode->Element = Current->Element;
            Current->Element = Current->Down->Right->Element;
        }
        else
            Current = Current->Down;
    }

    //必要時提高節點的高度(這里必要是保證header始終在最高層)
    if(L->Right != Tail )
    {
        NewNode = malloc( sizeof(struct SkipNode ));
        if(NewNode == NULL )
            Error("out of space");

        NewNode->Right = Tail;
        NewNode->Down = L;
        NewNode->Element = Infinity;
        L= NewNode;
    }
    return L;
}

??簡析:上圖解釋:
?????變量解析:

變量 L C B D R N
含義 根(頂)節點 當前節點 底(臨時)節點 Down指針 Right指針 新建節點

首先把 5 放到臨時結構體 Bottom 中,
條件while(Item > Current->Element ) 判斷不成立 ; ?
條件 if( Current->Element > Current->Down->Right->Right->Element ) 成立;
然后新建節點N,交換指針,賦值;
條件if(L->Right != Tail ) 成立 ,新建節點交換指針并賦值;

插入 5 過程

插入 10 過程
插入 15 過程
插入 20 過程, 這里的插入是重點,理解這里,基本上就可以自己演算后面的插入操作了!


  • 查找操作

重點:while(item != current->Element)
???????

Position Find(ElementType item , SkipList L )
{
    Position current = L;

    Bottom->Element = item;
    while(item != current->Element)
    {
        if( item < current->Element )
        {
            current = current->Down;
        }
        else
            current = current->Right;
    }
    return current;
}

??簡析:理解了插入,對于查找來說,不成問題,放寬心看幾分鐘基本就明白了。我一開始看插入,費了好幾張A4紙來比劃,也是智商捉急了···· *?*

1-2-3確定性鏈表--簡圖



  • 學習ING

????? 暫時寫到這里,《數據結構與算法分析 C語言描述》連敲帶看半個月,到了11 、12章看得很是迷糊····
作為一名標準的機械男,居然不好好學切割焊銑,而從大一開始把三年的大部分美好時光傾情奉獻給了編程···,看電子和軟件方面的專業書比在修專業的還多····也不知是福是禍···。其實我想問這么一個問題:興趣廣泛,無一專精,于目前社會情況,是福是禍?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 課程介紹 先修課:概率統計,程序設計實習,集合論與圖論 后續課:算法分析與設計,編譯原理,操作系統,數據庫概論,人...
    ShellyWhen閱讀 2,339評論 0 3
  • 1. AVL樹 AVL樹簡單來說是帶有平衡條件的二叉查找樹.傳統來說是其每個節點的左子樹和右子樹的高度最多差1(注...
    fredal閱讀 1,843評論 0 4
  • 一、基本數據類型 注釋 單行注釋:// 區域注釋:/* */ 文檔注釋:/** */ 數值 對于byte類型而言...
    龍貓小爺閱讀 4,288評論 0 16
  • 一. 算法之變,結構為宗 計算機在很多情況下被應用于檢索數據,比如航空和鐵路運輸業的航班信息和列車時刻表的查詢,都...
    Leesper閱讀 6,988評論 13 42
  • 題記 一眼,癡纏千年, 一見,心城淪陷, 一念,往事成煙…… 黯云天,落木蕭蕭,燈火闌珊,北城一別歸無期, 紛飛燕...
    穿越者木易君閱讀 1,640評論 84 85