《大話資料結構》 學習筆記9 重點

2021-06-06 11:34:50 字數 3468 閱讀 5194

單鏈表和順序儲存結構的區別:

1.單鏈表不像順序儲存結構這麼集中,它可以很散,是一種動態結構;

2.對每個鍊錶來說,它所占用空間的大小和位置是不需要預先分配劃定的,可以根據系統的情況和實際的需求即時生成。

所建立單鏈表

的過程就是乙個動態生成鍊錶的過程。即從「空表」的初始化狀態起,依次建立各元素結點,並逐個插入鍊錶。

單鏈表整表建立的演算法思路

1.宣告乙個結點p和計數器變數i;

2.初始化一空鍊錶l;

3.讓l的頭結點的指標指向null,即建立乙個帶頭結點的單鏈表;

4.迴圈:

&  生成一新結點賦值給p;

&  隨機生成一數字賦值給p的資料域p->data;

&  將p插入到頭結點與前一新結點之間;

實現單鏈表整表建立**演算法如下:

/*隨機產生n個元素的值,建立帶表頭結點的單鏈線性表l(頭插法)*/

void createlisthead  (linklist  *l, int n )

}

這段演算法**裡,我們其實用的是插隊的辦法,就是始終讓新結點在第一的位置。我們可以把這種演算法簡稱為頭插法。如圖:

可事實上,我們還是可以不這樣幹,為什麼不把新結點都放最後呢?這才是排隊的正常思維,所謂先來後到。

我們把每次新結點都插在終端結點的後面,這種演算法稱之為尾插法

實現尾插法**演算法如下:

/*隨機產生n個元素的值,建立帶表頭結點的單鏈線性表l(尾插法)*/

void createlisttail (linklist  *l, int n )

r->next = null; /*表示當前鍊錶結束*/

}

注意l與r的關係,l是指整個單鏈表,而r是指向尾結點的變數,r會隨著迴圈的不斷變化結點,而l則是隨著迴圈增長為乙個多結點的鍊錶。

這裡需要解析一下,r->next=p  是將剛才的表尾端結點r的指標指向新結點p;  (難點:)  r =p就不是很好理解了,是什麼意思?看圖:

它的意思是,就是本來r是在ai-1元素的結點,可現在它已經不是最後的結點了。(其實r就是乙個尾節點的標誌,當r沒有在尾時,必須把它移到尾)

迴圈結束,那麼應該讓這個鍊錶指標域置空,因此有了「r->next=null」以便以後遍歷時可以確認其尾部。

個人思考附加:

附加一:

頭插法尾插法區別:

頭插法:頭指標裝null,每次從後面新增元素,null尾都要往後挪乙個地方;

尾插法:頭指標沒有裝null,每次從後面新增元素,新增完後,再在尾指標裝null;

附加二:

srand函式是隨機數發生器的初始化函式。

原型:void srand(unsigned seed);

用法:它需要提供乙個種子,這個種子會對應乙個隨機數,如果使用相同的種子後面的rand()函式會出現一樣的隨機數。如: srand(1); 直接使用1來初始化種子。不過為了防止隨機數每次重複常常使用系統時間來初始化,即使用 time函式來獲得系統時間,它的返回值為從 00:00:00 gmt, january 1, 1970 到現在所持續的秒數,然後將time_t型資料轉化為(unsigned)型再傳給srand函式,即: srand((unsigned) time(&t)); 還有乙個經常用法,不需要定義time_t型t變數,即: srand((unsigned) time(null)); 直接傳入乙個空指標,因為你的程式中往往並不需要經過引數獲得的t資料。

函式一:int rand(void);

從srand (seed)中指定的seed開始,返回乙個[seed, rand_max(0x7fff))間的隨機整數。

函式二:void srand(unsigned seed);

引數seed是rand()的種子,用來初始化rand()的起始值。

可以認為rand()在每次被呼叫的時候,它會檢視:

1) 如果使用者在此之前呼叫過srand(seed),給seed指定了乙個值,那麼它會自動呼叫

srand(seed)一次來初始化它的起始值。

2) 如果使用者在此之前沒有呼叫過srand(seed),它會自動呼叫srand(1)一次。

根據上面的第一點我們可以得出:

1) 如果希望rand()在每次程式執行時產生的值都不一樣,必須給srand(seed)中的seed乙個變值,這個變值必須在每次程式執行時都不一樣(比如到目前為止流逝的時間)。

2) 否則,如果給seed指定的是乙個定值,那麼每次程式執行時rand()產生的值都會一樣,雖然這個值會是[seed, rand_max(0x7fff))之間的乙個隨機取得的值。

3) 如果在呼叫rand()之前沒有呼叫過srand(seed),效果將和呼叫了srand(1)再呼叫rand()一樣(1也是乙個定值)。

rand () %100   即隨機生成100以內的數;

當我們不打算使用這個單鏈表時,我們需要把它銷毀,其實也就是在記憶體中將它釋放掉,以便留出空間給其他程式設計師或軟體使用。

單鏈表的整表刪除的演算法思路如下:

1.宣告一結點p和q;

2.將第乙個結點賦值給p;

3.迴圈:

&  將下一結點賦值給q;

&  釋放p;

&  將q賦值給p;

實現單鏈表的整表刪除**演算法如下

/*初始化條件:順序線性表l已存在,操作結果:將l重置為空表*/

status  clearlist  (linklist   *l)

(*l)->next =null; /*頭結點指標域為空*/

return ok;

}

這段**裡,常見的錯誤就是由同學會覺得q變數沒有存在的必要。在迴圈體內直接寫free(p);p=p->next ;即可,可這樣帶來什麼問題?

要知道p是乙個結點,它除了有資料域,還有指標域。你在做free(p)時,其實時在對它整體結點進行刪除和記憶體釋放工作。

怎麼說呢?你看懂《大話資料結構》--學習筆記9 ***重點***

尾插法中的那句:「r=p」 了嗎?如果看懂了 ,這個也應該沒問題的。因為他們類似的,都起到乙個指標傳遞的作用。

《大話資料結構》 學習筆記1

第一章 資料結構緒論 經典 if you give someone a program you will frustrate them for a day if you teach tem how to program,you will frustrate them for a lifetim.如果...

《大話資料結構》 學習筆記2

第二章 演算法 2.2 資料結構 與 演算法的關係 簡單的說 資料結構 與 演算法 的關係 即 梁山伯 與 祝英台 的關係 把其中一方隔離出來唱獨角戲.沒意義!2.3 兩種演算法的比較 現寫乙個求1 2 3 100結果的程式,你應該怎麼寫呢?大多數人馬上寫出下面的c語言 int i,sum 0,n ...

《大話資料結構》 學習筆記5

線性表的順序儲存結構,指的是用一段位址連續的儲存單元依次儲存線性表的資料元素。線性表 a1,a2,a3,an 的順序儲存示意圖如下 a1a2 ai 1 ai.an 線性表的順序儲存結構,說白了,就是 在記憶體中找了塊地兒,通過佔位的形式,把一定的記憶體空間給佔了,然後把相同資料型別的資料元素一次存放...