最常用的資料結構有list、list、string、map。我們已經練習過list和string,現在練習list,雙向鍊錶。
注意雙向鍊錶有多種變形,比如非環結果雙向鍊錶,普通環行雙向鍊錶,多乙個頭節點的環行雙向鍊錶。不同的變形版本,對**的複雜度有很微妙的影響。
typedef struct
list;
提供如下形式的演算法函式
1)list create(void);
建立乙個空鍊錶,裡面元素個數為0
list create_n(int n);
建立乙個空鍊錶,裡面元素個數為n,每個元素都呼叫init_t函式進行了賦初值。
list create_n_t(int n, t t);
建立乙個空鍊錶,裡面元素個數為n,每個元素都賦初值為t。
voiddestory(list *);
銷毀掉鍊錶,**記憶體
2)int size(list *);
獲得list裡的元素個數
3)t * front(list *);
獲得list裡的第乙個元素的指標。請說明元素個數為0時,你的函式返回什麼結果
t * back(list *);
獲得list裡的最後乙個元素的指標。請說明元素個數為0時,你的函式返回什麼結果
4)t * begin(list *); t * end(list *);
返回的2個指標構成半閉半開區間[begin, end)指示出煉表裡所有元素。
所謂半閉半開區間就是包括begin所指元素,但不包括end所指元素。半閉半開區間是資料使用上乙個極重要的概念,因為它能表示空集合。配合下面的next,你就可以在不管是否有元素的情況下都可簡單地進行遍歷了。
for (t * p = begin(&v); p != end(&v); next(&v, p))
t * next(list *, t *);
假定傳入的指標確保指向list裡的某個元素,給出它的下乙個元素的指標。請說明已經指向最後乙個元素時,你的函式返回什麼結果。
t * prev(list *, t *);
假定傳入的指標確保指向list裡的某個元素,給出它的前乙個元素的指標。請說明已經指向第乙個元素時,你的函式返回什麼結果。
5)t * find(list *, t t);
搜尋第乙個值為t的元素,返回其指標。請說明沒找到時,你的函式返回什麼結果。
int count(list *, t t);
計算值為t的元素的個數
6)t * insert(list *, t * pos, t t);
將t插入到指標pos所指元素之前。返回新插入的元素的指標。
t * insertrange(list *, t * pos, t * first, t * last);
將[first, last)所指區間中所有元素保持原順序插入到pos所指元素之前。返回新插入的第乙個元素的指標。
void push_back(list *
,t t);在鍊錶最後追加乙個元素。
void push_front(list *, t t);
在鍊錶最開頭增加乙個元素。
t * erase(list *, t * pos);
刪除指標pos所指元素。返回被刪除的元素的下乙個元素的現在的指標。
t * eraserange(list *, t * first, t * last);
刪除指標[first, last)所指區間中的元素。返回最後乙個刪除的元素的下乙個元素的現在的指標。
void pop_back(list *, t t);
刪除最後乙個元素。
void pop_front(list *, t t);
刪除最開頭的那個元素。
void clear(list *);
清空所有元素。
bool remove(list *, t t);
刪除所有值為t的元素。返回「是否進行了刪除」。
7)void assign(list * l, const list * r);
使得l所指記憶體擁有和r完全相同的元素,而不是l.p和r.p指向相同的位址。注意記憶體的分配和釋放。
void swap(list * l, list * r);
使得l擁有原來r的元素,r擁有l原來的元素。
list create_bylist(const list * v)//
建立和v具有完全相同元素的新list
list create_byarray(const t * first, const t * last)//
建立和[first, last)所指陣列區間相同的元素的新list 8)
附加題:
bool empty(const list * v)//
如果沒有元素,返回true,其它情況返回flase
voidassign_byarray(list * v, const t * first, const t * last)//
使得v現在含有和[first, last)所指陣列區間相同的元素
bool equal(const list * l, const list * r)//
當2個list元素個數並且按順序,每個元素都相同時,返回true
bool less(const list * l, const list * r)//
按字典序進行比較,l < r時返回true。字典序就是a開始的所有單詞< b開頭的所有單詞;a在所有a開頭的單詞裡最小;其它a開頭的單詞根據第二個字母起繼續比較。
9)提高題:
實現find、count、remove操作的擴充套件。
要能完成比如「count(list *, ******);能計算所有值大於x的元素的個數」這樣的通用問題。
10)再提高題:
list
用create函式建立後,因為分配了記憶體,所以必須用destory銷毀的。而且每create一次,就得有且僅有一次對應的destory。
如果有如下**list v1 = create_n(2);
list v2 = create_n(3);
v2 = v1;
那麼將導致v2在create過程中分配的記憶體就洩漏了。
所以,問題是:如何能防止不小心的v2 = v1這類行為?
在你們的list**裡想辦法完成,而不是指望使用list的人總不犯錯。
c 初級 之 vector與list對比
1.vector資料結構 vector和陣列類似,擁有一段連續的記憶體空間,並且起始位址不變。因此能高效的進行隨機訪問,時間複雜度為o 1 但因為記憶體空間是連續的,所以在進行插入和刪除操作時,會造成記憶體塊的拷貝,時間複雜度為o n 另外,當陣列中記憶體空間不夠時,會重新申請一塊記憶體空間並進行記...
乙個適合初級 Gopher 練手的專案
本專案見github market monitor 這是乙個初級 gopher 練手的小專案 該專案功能簡單,主要實現監測幣市 變化 達到預警效果的功能,大致的使用場景如下 使用者登入服務 使用者設定關注的幣種及預警的走勢 當 變化觸發到使用者的預警設定時,服務將自動傳送提醒郵件通知使用者 整體功能...
java練手題二之類基本
每個類可以分為兩個部分 乙個是屬性與狀態,乙個是類的行為 專業點講就是 域和各種方法 要把構造方法區別對待 1.域 例項變數 用來儲存某個類物件的狀態值。其修飾符可以是public或private,但不能為static。與物件共存亡。靜態變數 static關鍵字,儲存在類的儲存空間的公共儲存單元中,...