1,二叉樹深度優先遍歷和廣度優先遍歷
深度優先遍歷:對每一個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次。要特別注意的是,二叉樹的深度優先遍歷比較特殊,剋細分為 前序遍歷,中序遍歷,后序遍歷 (小竅門:看根節點再前中后?)
前序遍歷:根節點->左節點->右子樹
中序遍歷:左子樹->根節點->右子樹
后序遍歷:左子樹->右子樹->根節點
廣度優先遍歷:又叫層次遍歷,從上往下對每一層依次訪問,在每一層中,從左往右(也可以從右往左)訪問結點,訪問完一層就進入下一層,直到沒有結點可以訪問為止。
二叉樹的深度優先遍歷的非遞歸的通用做法是采用棧,廣度優先遍歷的非遞歸的通用做法是采用隊列。
2,堆和棧的區別
(1)堆是一個完全二叉樹,而且某個節點的值總是不大於或不小於父節點的值(有最大堆和最小堆)
棧是一個先進后出的線性表,(在棧頂進行操作)
(2)堆的存取是隨意的,這就如同我們在圖書館的書架上取書,雖然書的擺放是有順序的,但是我們想取任意一本時不必像棧一樣,先取出前面所有的書,書架這種機制不同於箱子,我們可以直接取出我們想要的書
(3)內存的申請方式不同
棧:由操作系統(編譯器)自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
堆: 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似於鏈表。
(4)內存的申請效率不同
棧:棧由系統自動分配,速度較快
堆:堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便
(5)申請大小的限制
棧:是連續內存 在window里面,棧的大小是2M,如果空間過大的話,會提示overflow
堆:不是連續內存,堆獲得的空間比較靈活,也比較大
(6)緩存方式
棧:使用的是一級緩存,通常都是被調用的時候處於存儲空間中,調用完立即釋放
堆:放在二級緩存中,生命周期由虛擬機的垃圾回收算法來決定(並不是一旦成為孤兒對象就能被回收)。所以調用這些對象的速度相對來說更低。
(關於一級內存,二級內存:https://blog.csdn.net/penghuasheng/article/details/1761566)
(7)回收方式
棧:由於棧上的空間是自動分配自動回收的,所以棧上的數據的生存周期只是在函數的運行過程中,運行后就釋放掉,不可以再訪問。
堆:堆上的數據只要程序員不釋放空間,就一直可以訪問到,不過缺點是一旦忘記釋放會造成內存泄露
第二題借鑒以下博客:
https://blog.csdn.net/langb2014/article/details/79376349
https://www.jianshu.com/p/5f148c3e4f7d
3,鏈表反轉
例如: 輸入: 1->2->3->4->5->NULL 輸出: 5->4->3->2->1->NULL
設置兩個指針 new(剛剛修改完的界定),old(沒有修改的老的節點),
把old的指針指向new,所以這個時候需要記錄old的下一個節點,即 tmp=old->next
這時 把new=old old=tmp 開始下一輪的循環
偽代碼:
while(old!=null){ tmp=old->next old->next=new new=old old=tmp }
擴展:
要把 head->1->2->3->4->5->6
改成 head->4->3->2->1->5->6
如下代碼:(前面加一個頭指針會更好處理)
ptr reverse(ptr head,int k) { cnt=1; new=head->next; old=new->next; while( cnt < K ){ tmp = old->next; old->next = new; new = old; old = tmp; cnt++; } head->next->next = old; return new; }
鏈表逆轉學習通過:
https://haokan.baidu.com/v?vid=17680630196571888503&pd=bjh&fr=bjhauthor&type=video
4,紅黑樹:
紅黑樹的特性和優勢,在神魔情況下需要變色,在神魔情況下需要旋轉
紅黑樹是基於二叉查找樹的
二叉查找樹的特性:
1.左子樹上所有結點的值均小於或等於它的根結點的值。
2.右子樹上所有結點的值均大於或等於它的根結點的值。
3.左、右子樹也分別為二叉排序樹。
查找的方式正是二分查找的思想,查找所需的最大次數等同於二叉查找樹的高度。
在插入節點的時候也是利用類似的方法,通過一層層比較大小,找到新節點適合插入的位置
但是插入數據的時候,二叉查找樹的性能可能會降低(變成瘸子)
然后紅黑樹就應運而生
紅黑樹是一種自平衡的二叉查找樹,除了符合二叉查找樹的基本特性外,還有下面的附加特性
1.節點是紅色或黑色。
2.根節點是黑色。
3.每個葉子節點都是黑色的空節點(NIL節點)。
4 每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)
5.從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。
紅黑樹從樣子的最長路徑不會超過最短路徑的二倍
當插入或刪除節點的時候,紅黑樹的規則有可能會被打破,這時候需要做一些調整來維持規則
調整的方法有兩種:變色和旋轉(左旋轉和右旋轉)
紅黑樹參考博客:
https://blog.csdn.net/qq_36610462/article/details/83277524
另外,關於數據結構和算法的基礎文檔有:
基礎文檔1