鍊錶由單向的鏈變成雙向鏈,使用這種資料結構,我們不再拘束於單鏈表的單向建立於遍歷等操作。
在單鏈表中,有乙個資料域,還有乙個指標域,資料域用來儲存相關資料,而指標域負責鍊錶之間的「聯絡」。在雙向鍊錶中,需要有兩個指標域,乙個負責向後連線,乙個負責向前連線。
//單鏈表的結構
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 對簡單選擇排序的一種改...