資料結構與演算法(三)

2022-07-06 00:15:11 字數 4123 閱讀 9184

鍊錶由單向的鏈變成雙向鏈,使用這種資料結構,我們不再拘束於單鏈表的單向建立於遍歷等操作。

在單鏈表中,有乙個資料域,還有乙個指標域,資料域用來儲存相關資料,而指標域負責鍊錶之間的「聯絡」。在雙向鍊錶中,需要有兩個指標域,乙個負責向後連線,乙個負責向前連線

//單鏈表的結構

struct list;

//雙向鍊錶的結構

typedef struct list;

typedef struct list* pelem;

typedef struct list eelem;

同單鏈表一樣,對雙向鍊錶的操作也有建立,插入,遍歷,刪除,銷毀。

雙向鍊錶的建立

在建立雙向鍊錶的時候,需要初始化兩個指標。同單鏈表一樣,需要乙個頭指標來標誌鍊錶的資訊。可以寫出該函式的定義:

pelem createlist()
雙向鍊錶的插入

在單向鍊錶的頭插法中,最主要的語句就是tmp->next = head->next,而在雙向鍊錶中,多了乙個向前的指標。

void insertelem( pelem head, int data )

pelem tmphead = head; //建立乙個臨時的頭結點指標

建立乙個新的結點addition,此時表中只有頭結點,因此執行if中的程式,執行完畢後就變成了:

雙向鍊錶的遍歷

在遍歷中將實現next的向後遍歷,也會實現front的向前遍歷

void illulist( pelem head )

pelem tmphead = head;

while( tmphead->next != null )

//此時tmphead的位址在鍊錶的最後乙個結點處

while( tmphead->front->front != null )

printf("%d\n", tmphead->data);

return;

}

當向後遍歷完成之後,此時tmphead的位址是鍊錶的最後乙個結點的位址,因此使用front來進行向前的遍歷,如果判斷條件是tmphead->front !=null的話,會將頭結點的資料域也輸出,然而頭結點的資料域未使用,因此會輸出乙個不確定的值。正因此判斷條件改為tmphead->front->front !=null刪除乙個結點

當刪除乙個結點的時候,我們要判斷在鍊錶中是否存在與之匹配的結點,有的話刪除成功,否則失敗。

就像這幅圖一樣,當刪除addition結點時,先講addition的下乙個結點與head相連,而下乙個結點是null,因此可以得出函式為:

void deleteelem( pelem head, int data )

pelem tmphead = head;

while( tmphead->next != null )

} free(tmphead); //釋放記憶體

}

銷毀鍊錶

銷毀乙個雙向鍊錶的操作同單鏈表的相似。指標不斷向後運動,每運動乙個結點,釋放上乙個結點。

此時,tmp的位址就是head的位址,但當執行乙個之後,就變成這樣。

上一次執行完之後,頭結點已經被釋放,此時頭結點就在第乙個資料結點處。以此往後,最後迴圈結束,釋放最後乙個結點。

課堂演示題目

要求實現使用者輸入乙個數使得26個字母的排列發生變化,例如使用者輸入3,輸出結果:

同時需要支援負數,例如使用者輸入-3,輸出結構:

棧:(stack)是乙個後進先出(last in first out ,lifo)的線性表,它要求只在表尾進行刪除和插入操作。

對於棧來說,表尾稱為棧的棧頂(top),相應的表頭稱為棧底(bottom)。

棧的順序儲存結構

typedef struct

sqstack;

base是指向棧底的指標變數,top是指向棧頂的指標變數,stacksize指示棧的當前可使用的最大容量。

建立乙個棧

#define stack_init_size 100

initstack(sqstack *s)

入棧操作
#define stackincrement 10

push(sqstack *s, elemtype e)

*(s->top) = e;

s->top++;

}

出棧操作銷毀乙個棧

計算棧的當前容量

例項分析

棧的鏈式儲存結構

進棧操作

對於棧鏈的push操作,假設元素值為e的新結點是s,top為棧頂指標

status push(linkstack *s, elemtype e)

出棧操作

假設變數p用來儲存要刪除的棧頂結點,將棧頂指標下移一位,最後釋放p即可

status pop(linkstack *s, elemtype *e )

#include #include #include #define stack_init_size 20

#define stackincrement 10

#define maxbuffer 10

typedef double elemtype;

typedef struct

sqstack;

initstack(sqstack *s)

push(sqstack *s, elemtype e)

*(s->top) = e; // 存放資料

s->top++;

}pop(sqstack *s, elemtype *e)

int stacklen(sqstack s)

int main()

scanf("%c", &c);

if( c == ' ' )

}switch( c )

else

break;

}scanf("%c", &c);

}pop(&s, &d);

printf("\n最終的計算結果為:%f\n", d);

return 0;

}

資料結構與演算法(三)

變位詞是指兩個詞之間存在組成字母的 重新排列關係 如 heart和earth,python和typhon 為了簡單起見,假設參與判斷的兩個詞僅由小寫 字母構成,而且長度相等 詞1中的字元逐個在詞2中檢查是否存在,存在則標記防止重複檢查。如果每個字元都能找到,並且詞1詞2長度相同則是變位詞。否則不是。...

演算法與資料結構筆記三

摘錄from 大話資料結構 1.樹 樹的度 結點擁有的子樹數成為結點的度 degree 度為0的結點成為葉節點 leaf 或終端結點。樹的深度或高度 結點的層次level,從根節點開始,根為第一層,根的孩子為第二層。樹中最大層次稱為樹的深度 depth 或高度,當前樹的深度為4.樹的儲存 樹儲存當然...

資料結構與演算法 排序 三

假設初始序列含有n個記錄,則可以看成是n個有序的子串行,每個子串行的長度為1,然後兩兩歸併,得到 n 2 個長度為2或者1的有序子串行 再兩兩歸併,如此重複,直至得到乙個長度為n的有序序列為止。歸併排序是一種比較占用記憶體,但是卻效率高並穩定的演算法,時間複雜度是o logn 對簡單選擇排序的一種改...