一 單鏈表
目錄
?
?
首先寫一個單鏈表的C#實現
public class Link
{
public Link Next;
public string Data;
public Link(Link next
{
this
this
}
}
?
?
其中
?
?
?
對一個單鏈表的遍歷如下所示
static void Main(string[] args)
{
Link head = GenerateLink();
Link curr = head;
while (curr != null)
{
Console
curr = curr
}
}
?
?
單鏈表反轉
這道題目有兩種算法
算法
public static Link ReverseLink
{
Link curr = head
Link next = null;
Link nextnext = null;
//if no elements or only one element exists
if (curr == null || curr
{
return head;
}
//if more than one element
while (curr
{
next = curr
nextnext = next
next
head
curr
}
return head;
}
?
?
算法的核心是while循環中的
?
?
我們發現
此外
?
?
算法
如果題目簡化為逆序輸出這個單鏈表
public static void ReverseLink
{
if (head
{
ReverseLink
Console
}
}
?
?
但是
首先
public static Link ReverseLink
{
//if no elements or only one element exists
if (head
return head;
head
return head;
}
?
?
我們觀測到
head
這句話的意思是為ReverseLink方法生成的逆序鏈表添加一個空表頭
接下來就是遞歸的核心算法ReverseLink了
static Link ReverseLink(Link head)
{
if (head
return head;
Link rHead = ReverseLink(head
head
head
return rHead;
}
?
?
算法的關鍵就在於遞歸後的兩條語句
head
head
啥意思呢?畫個圖表示就是
?
?
這樣
?
?
找出單鏈表的倒數第 個元素
這道題目有兩種算法
第
static Link GetLast
{
Link first = head;
Link second = head;
for (int i =
{
if (first
throw new Exception(
first = first
}
while (first != null)
{
first = first
second = second
}
return second;
}
?
?
第
static Link GetLast
{
Link curr = head;
int i =
Link[] arr = new Link[
while (curr
{
arr[i] = curr
curr = curr
i = (i +
}
if (arr[i] == null)
throw new Exception(
return arr[i];
}
?
?
本題目源代碼下載
推而廣之
?
?
找出單鏈表的中間元素
算法思想
static Link GetMiddleOne(Link head)
{
Link first = head;
Link second = head;
while (first != null && first
{
first = first
second = second
}
return second;
}
但是
下面是加強版的算法
static void Main(string[] args)
{
Link head = GenerateLink();
bool isOdd = true;
Link middle = GetMiddleOne(head
if (isOdd)
{
Console
}
else
{
Console
Console
}
Console
}
static Link GetMiddleOne(Link head
{
Link first = head;
Link second = head;
while (first != null && first
{
first = first
second = second
}
if (first != null)
isOdd = false;
return second;
}
?
?
一個單鏈表 很長 遍歷一遍很慢 我們僅知道一個指向某節點的指針curr 而我們又想刪除這個節點
這道題目是典型的
?
?
如果不考慮任何特殊情況
curr
?
curr
上述代碼由一個地方需要注意
?
?
此外
相關問題
話說
?
?
兩個不交叉的有序鏈表的合並
有兩個有序鏈表
算法思路
注意
static Link MergeTwoLink(Link head
{
Link head = new Link(null
Link pre = head;
Link curr = head
Link curr
Link curr
//compare until one link run to the end
while (curr
{
if (curr
{
curr = new Link(null
curr
}
else
{
curr = new Link(null
curr
}
pre
pre = pre
}
//if head
while (curr
{
curr = new Link(null
curr
pre
pre = pre
}
//if head
while (curr
{
curr = new Link(null
curr
pre
pre = pre
}
return head;
}
?
?
如果這兩個有序鏈表交叉組成了Y型呢
?
這時我們需要先找出這個交叉點(圖中是
然後局部修改上面的算法
static Link MergeTwoLink
{
Link head = new Link(null
Link pre = head;
Link curr = head
Link intersect = GetIntersect(head
Link curr
Link curr
//compare until one link run to the intersect
while (curr
{
if (curr
{
curr = new Link(null
curr
}
else
{
curr = new Link(null
curr
}
pre
pre = pre
}
//if head
if (curr
{
while (curr
{
curr = new Link(null
curr
pre
pre = pre
}
}
//if head
else if (curr
{
while (curr
{
curr = new Link(null
curr
pre
pre = pre
}
}
return head;
}
?
?
有個二級單鏈表 其中每個元素都含有一個指向一個單鏈表的指針 寫程序把這個二級鏈表展開稱一級單鏈表
這個簡單
public class Link
{
public Link Next;
public int Data;
public Link(Link next
{
this
this
}
}
public class CascadeLink
{
public Link Next;
public CascadeLink NextHead;
public CascadeLink(CascadeLink nextHead
{
this
this
}
}
?
?
下面做一個二級單鏈表
public static CascadeLink GenerateCascadeLink()
{
Link head
Link head
Link head
CascadeLink element
CascadeLink element
CascadeLink element
CascadeLink head = new CascadeLink(element
return head;
}
就是說
–>
?
?
我們的算法思想是
public static Link GenerateNewLink(CascadeLink head)
{
CascadeLink curr
Link newHead = curr
Link curr
while (curr
{
curr
while (curr
{
curr
}
curr
}
return newHead;
}
?
?
其中
?
?
單鏈表交換任意兩個元素(不包括表頭)
先一次遍歷找到這兩個元素curr
然後大換血
public static Link SwitchPoints(Link head
{
if (p == head || q == head)
throw new Exception(
if (p == q)
return head;
//find p and q in the link
Link curr = head;
Link curr
Link curr
Link pre
Link pre
?
int count =
while (curr != null)
{
if (curr
{
pre
count++;
if (count ==
break;
}
else if (curr
{
pre
count++;
if (count ==
break;
}
curr = curr
}
curr = curr
pre
curr
pre
curr
return head;
}
注意特例
?
?
判斷單鏈表是否有環?如何找到環的 ;起始 ;點?如何知道環的長度?
算法思想
先分析是否有環
static bool JudgeCircleExists(Link head)
{
Link first = head; //
Link second = head; //
while (second
{
second = second
first = first
if (second == first)
return true;
}
return false;
}
?
?
那又如何知道環的長度呢?
根據上面的算法
static int GetCircleLength(Link point)
{
int length =
Link curr = point;
while (curr
{
length++;
curr = curr
}
return length;
}
?
?
繼續我們的討論
延續上面的思路
static int GetLengthFromHeadToPoint(Link head
{
int length =
Link curr = head;
while (curr != point)
{
length++;
curr = curr
}
return length;
}
?
?
如果我們把環從P點
一個單鏈表是從P點出發
我們可以參考第
private static Link FindIntersect(Link head)
{
Link p = null;
//get the point in the circle
bool result = JudgeCircleExists(head
if (!result) return null;
Link curr
Link curr
//length from head to p
int M =
while (curr
{
M++;
curr
}
//circle length
int N =
while (curr
{
N++;
curr
}
//recover curr
curr
curr
//make
if (M > N)
{
for (int i =
curr
}
else if (M < N)
{
for (int i =
curr
}
//goto the intersect
while (curr
{
if (curr
{
return curr
}
curr
curr
}
return null;
}
?
?
判斷兩個單鏈表是否相交
這道題有多種算法
算法
static bool JudgeIntersectLink
{
Hashtable ht = new Hashtable();
Link curr
Link curr
//store all the elements of link
while (curr
{
ht[curr
curr
}
//check all the elements in link
while (curr
{
//if exists
if (ht[curr
{
return true;
}
curr
}
return false;
}
?
?
算法
注意
static bool JudgeIntersectLink
{
bool exists = false;
Link curr
Link curr
?
//goto the end of the link
while (curr
{
curr
}
//join these two links
curr
//iterate link
while (curr
{
if (curr
{
exists = true;
break;
}
curr
}
//recover original status
curr
return exists;
}
?
?
算法
static bool JudgeIntersectLink
{
Link curr
Link curr
//goto the end of the link
while (curr
{
curr
}
//goto the end of the link
while (curr
{
curr
}
if (curr
return false;
else
return true;
}
?
兩個單鏈表相交 計算相交點
分別遍歷兩個單鏈表
public static Link GetIntersect(Link head
{
Link curr
Link curr
int M =
//goto the end of the link
while (curr
{
curr
M++;
}
//goto the end of the link
while (curr
{
curr
N++;
}
//return to the begining of the link
curr
curr
if (M > N)
{
for (int i =
curr
}
else if (M < N)
{
for (int i =
curr
}
while (curr
{
if (curr
{
return curr
}
curr
curr
}
return null;
}
?
?
用鏈表模擬大整數加法運算
例如
肯定是使用遞歸啦
此外對於
//head
public static int Add(Link head
{
// goto the end
if (head
return
int temp =
int result =
newHead = new Link(null
if (M > N)
{
result = Add(head
temp = head
newHead
return temp >=
}
else // M == N
{
result = Add(head
temp = head
newHead
return temp >=
}
}
這裡假設head
?
?
單鏈表排序
無外乎是冒泡
在實踐中
所以我最終選擇了插入排序算法
先給出基於數組的算法
?
?
代碼
static int[]
InsertSort(int[] arr)
{
for(int i=
{
for(int j =i; (j>
{
arr[j]=arr[j]^arr[j
arr[j
arr[j]=arr[j]^arr[j
}
}
?
return arr;
}
仿照上面的思想
public static Link SortLink(Link head)
{
Link pre
Link pre
Link min = null;
for (Link curr
{
if (curr
break;
min = curr
for (Link curr
{
//swap curr
if (curr
{
min = curr
curr
curr
pre
curr
curr
//if exchange element n
if (pre
pre
}
pre
}
pre
pre
}
return head;
}
?
?
值得注意的是
?
?
交換指針很是麻煩
?
?
刪除單鏈表中重復的元素
用Hashtable輔助
實踐中發現
public static Link DeleteDuplexElements(Link head)
{
Hashtable ht = new Hashtable();
Link curr = head;
while (curr != null)
{
if (curr
{
break;
}
if (ht[curr
{
curr
}
else
{
ht[curr
}
curr = curr
}
return head;
}
?
?
?
?
結語
單鏈表只有一個向前指針Next
盡量用while循環而不要用for循環
哇塞
遍歷的時候
有時我們需要臨時把環切開
究竟是玩curr還是curr
?
?
二 棧和隊列
?
目錄
?
?
?
設計含min函數的棧 要求min push和pop的時間復雜度都是o( )
算法思想
所以
此外
?
public class NewStack
{
private Stack dataStack;
private Stack mindataStack;
public NewStack()
{
dataStack = new Stack();
mindataStack = new Stack();
}
public void Push(int element)
{
dataStack
if (mindataStack
mindataStack
else if (element <= (int)mindataStack
mindataStack
else //(element > mindataStack
mindataStack
}
?
public int Pop()
{
if (dataStack
throw new Exception(
?
mindataStack
return (int)dataStack
}
public int Min()
{
if (dataStack
throw new Exception(
?
return (int)mindataStack
}
}
?
?
?
設計含min函數的棧的另解
話說
算法代碼如下所示(這裡最小元素位於當前元素之上
public class NewStack
{
private Stack stack;
public NewStack()
{
stack = new Stack();
}
public void Push(int element)
{
if (stack
{
stack
stack
}
else if (element <= (int)stack
{
stack
stack
}
else //(element > stack
{
object min = stack
stack
stack
}
}
public int Pop()
{
if (stack
throw new Exception(
stack
return (int)stack
}
public int Min()
{
if (stack
throw new Exception(
return (int)stack
}
}
?
?
之所以說我這個算法比較叩門
?
?
?
?
用兩個棧實現隊列
實現隊列
按照上述分析
public class NewQueue
{
private Stack stack
private Stack stack
public NewQueue()
{
stack
stack
}
public void Enqueue(int element)
{
stack
}
public int Dequeue()
{
if (stack
{
if (stack
throw new Exception(
else
while (stack
stack
}
return (int)stack
}
public int Peek()
{
if (stack
{
if (stack
throw new Exception(
else
while (stack
stack
}
return (int)stack
}
}
?
?
?
用兩個隊列實現棧
這個嘛
至於Peek
那麼Push的操作
public class NewStack
{
private Queue queue
private Queue queue
public NewStack()
{
queue
queue
}
public void Push(int element)
{
if (queue
queue
else
queue
}
public int Pop()
{
if (queue
throw new Exception(
if (queue
{
while (queue
{
queue
}
//還剩一個
return (int)queue
}
else //queue
{
while (queue
{
queue
}
//還剩一個
return (int)queue
}
}
public int Peek()
{
if (queue
throw new Exception(
int result =
if (queue
{
while (queue
{
queue
}
//還剩一個
result = (int)queue
queue
}
else //queue
{
while (queue
{
queue
}
//還剩一個
result = (int)queue
queue
}
return result;
}
}
?
?
?
棧的push pop序列是否一致
輸入兩個整數序列
比如輸入的push序列是
?
?
網上的若干算法都太復雜了
先for循環把arr
static bool
JudgeSequenceIsPossible(int[] arr
{
Stack stack = new Stack();
for (int i =
{
stack
while(stack
{
stack
j++;
}
}
return stack
}
?
?
?
?
遞歸反轉一個棧 要求不得重新申請一個同樣的棧 空間復雜度o( )
算法思想
static void ReverseStack(ref Stack stack)
{
if (stack
return;
object top = stack
ReverseStack(ref stack);
if (stack
{
stack
return;
}
object top
ReverseStack(ref stack);
stack
ReverseStack(ref stack);
stack
}
?
?
給棧排個序
本題目是上一題目的延伸
static void Sort(ref Stack stack)
{
if (stack
return;
object top = stack
Sort(ref stack);
if (stack
{
stack
return;
}
object top
if ((int)top > (int)top
{
stack
Sort(ref stack);
stack
}
else
{
stack
Sort(ref stack);
stack
}
}
?
?
?
?
如何用一個數組實現兩個棧
繼續我所提倡的摳門兒思想
網上流傳著兩種方法
方法
采用交叉索引的方法
一號棧所占數組索引為
?
?
?
二號棧所占數組索引為
?
算法實現如下
public class NewStack
{
object[] arr;
int top
int top
public NewStack(int capticy)
{
arr = new object[capticy];
top
top
}
public void Push(int type
{
if (type ==
{
if (top
throw new Exception(
else
{
top
arr[top
}
}
else //type==
{
if (top
throw new Exception(
else
{
top
arr[top
}
}
}
public object Pop(int type)
{
object obj = null;
if (type ==
{
if (top
throw new Exception(
else
{
obj = arr[top
arr[top
top
}
}
else //type ==
{
if (top
throw new Exception(
else
{
obj = arr[top
arr[top
top
}
}
return obj;
}
public object Peek(int type)
{
if (type ==
{
if (top
throw new Exception(
return arr[top
}
else //type ==
{
if (top
throw new Exception(
return arr[top
}
}
}
?
?
?
方法
第一個棧A
?
第二個棧B
?
代碼實現如下
public class NewStack
{
object[] arr;
int top
int top
public NewStack(int capticy)
{
arr = new object[capticy];
top
top
}
public void Push(int type
{
if (top
throw new Exception(
if (type ==
{
arr[top
top
}
else //type==
{
top
arr[top
}
}
public object Pop(int type)
{
object obj = null;
if (type ==
{
if (top
throw new Exception(
else
{
top
obj = arr[top
arr[top
}
}
else //type ==
{
if (top
throw new Exception(
else
{
obj = arr[top
arr[top
top
}
}
return obj;
}
public object Peek(int type)
{
if (type ==
{
if (top
throw new Exception(
return arr[top
}
else //type ==
{
if (top
throw new Exception(
return arr[top
}
}
}
綜合比較上述兩種算法
?
?
如何用一個數組實現三個棧
最後
如果還使用交叉索引的辦法
讓我們只好使用上個題目的第
第
?
第
?
第
?
第
這個方法的好處是
public class NewStack
{
object[] arr;
int top
int top
int top
int top
bool isLeft;
public NewStack(int capticy)
{
arr = new object[capticy];
top
top
isLeft = true;
top
top
}
public void Push(int type
{
if (type ==
{
if (top
throw new Exception(
arr[top
top
}
else if (type ==
{
if (top
throw new Exception(
top
arr[top
}
else //type==
{
if (isLeft)
{
if (top
throw new Exception(
arr[top
top
}
else
{
if (top
throw new Exception(
arr[top
top
}
isLeft = !isLeft;
}
}
public object Pop(int type)
{
object obj = null;
if (type ==
{
if (top
throw new Exception(
else
{
top
obj = arr[top
arr[top
}
}
else if (type ==
{
if (top
throw new Exception(
else
{
obj = arr[top
arr[top
top
}
}
else //type==
{
if (top
throw new Exception(
if (isLeft)
{
top
obj = arr[top
arr[top
}
else
{
top
obj = arr[top
arr[top
}
isLeft = !isLeft;
}
return obj;
}
public object Peek(int type)
{
if (type ==
{
if (top
throw new Exception(
return arr[top
}
else if (type ==
{
if (top
throw new Exception(
return arr[top
}
else //type==
{
if (top
throw new Exception(
if (isLeft)
return arr[top
else
return arr[top
}
}
}
?
?
?
?
三 二叉樹
目錄
?
?
?
?
?
?
首先寫一個二叉樹的C#實現
public class BinNode
{
public int Element;
public BinNode Left;
public BinNode Right;
public BinNode(int element
{
this
this
this
}
?
public bool IsLeaf()
{
return this
}
}
?
?
二叉樹三種周游(traversal)方式
static void PreOrder(BinNode root)
{
if (root == null)
return;
//visit current node
Console
PreOrder(root
PreOrder(root
}
?
?
static void PostOrder(BinNode root)
{
if (root == null)
return;
PostOrder(root
PostOrder(root
//visit current node
Console
}
?
?
static void InOrder(BinNode root)
{
if (root == null)
return;
InOrder(root
//visit current node
Console
InOrder(root
}
?
?
我們發現
?
?
怎樣從頂部開始逐層打印二叉樹結點數據
有
算法
static void PrintTree
{
if (root == null) return;
BinNode tmp = null;
Queue queue = new Queue();
queue
while (queue
{
tmp = (BinNode)queue
Console
if (tmp
queue
if (tmp
queue
}
}
?
?
話說
?
?
算法
如果沒有Queue給我們用
public class Link
{
public Link Next;
public BinNode Data;
public Link(Link next
{
this
this
}
}
看過了Queue的實現
對於單鏈表而言
當first指針走不下去了
static void PrintTree
{
if (root == null) return;
Link head = new Link(null
Link first = head;
Link second = head;
while (first != null)
{
if (first
{
second
second = second
}
if (first
{
second
second = second
}
Console
first = first
}
}
?
?
如何判斷一棵二叉樹是否是平衡二叉樹
平衡二叉樹的定義
算法思路
static int GetDepth(BinNode root)
{
if (root == null)
return
int leftLength = GetDepth(root
int rightLength = GetDepth(root
return (leftLength > rightLength
leftLength : rightLength) +
}
?
?
注意這裡的+
static bool IsBalanceTree(BinNode root)
{
if (root == null)
return true;
int leftLength = GetDepth(root
int rightLength = GetDepth(root
int distance = leftLength > rightLength
leftLength
?
if (distance >
return false;
else
return IsBalanceTree(root
}
?
?
上述程序的邏輯是
?
?
設計一個算法 找出二叉樹上任意兩個節點的最近共同父結點 復雜度如果是O(n )則不得分
本題網上有很多算法
算法
static bool GetPositionByNode(BinNode root
{
if (root == null)
return false;
if (root == node)
{
stack
return true;
}
if (GetPositionByNode(root
{
stack
return true;
}
return false;
}
?
?
然後我們要同時彈出這兩個容器的元素
static BinNode FindParentNode(BinNode root
{
Stack stack
GetPositionByNode(root
Stack stack
GetPositionByNode(root
BinNode tempNode = null;
while (stack
{
tempNode = (BinNode)stack
stack
}
return tempNode;
}
?
?
算法
我們選擇一個
////
////
////
////
如果要找的是
我們發現
這時
由上面觀察
static bool GetPositionByNode(BinNode root
{
if (root == null)
return false;
if (root == node)
return true;
int temp = pos;
//這麼寫很別扭
pos = temp *
if (GetPositionByNode(root
{
return true;
}
else
{
//找不到左邊找右邊
pos = temp *
return GetPositionByNode(root
}
}
static int FindParentPosition(int larger
{
if (larger == smaller) return larger;
int left = GetLen(larger)
while (left >
{
larger = larger >>
left
}
while (larger != smaller)
{
larger = larger >>
smaller = smaller >>
}
return smaller;
}
static int GetLen(int num)
{
int length =
while (num !=
{
num = num >>
length++;
}
return length;
}
函數GetNodeByPosition的思想是
static BinNode GetNodeByPosition(BinNode root
{
if (num ==
int pow = (int)Math
//第一個位不算
num
while (pow >
{
if ((num &
root = root
else
root = root
pow
}
return root;
}
?
?
總結上面的
static BinNode FindParentNode(BinNode root
{
int pos
GetPositionByNode(root
int pos
GetPositionByNode(root
int parentposition =
if (pos
{
parentposition = FindParentPosition(pos
}
else //pos
{
parentposition = FindParentPosition(pos
}
return GetNodeByPosition(root
}
?
?
如何不用遞歸實現二叉樹的前序/後序/中序遍歷?
算法思想
下面詳細分析第
這個是最簡單的
前序遍歷是root
因為在第一個while循環中
static void PreOrder(BinNode root)
{
Stack stack = new Stack();
BinNode temp = root;
//入棧
while (temp != null)
{
Console
if (temp
stack
temp = temp
}
//出棧
while (stack
{
temp = (BinNode)stack
Console
while (temp != null)
{
if (temp
stack
temp = temp
}
}
}
//後序遍歷比較麻煩
static void PostOrder(BinNode root)
{
Stack stack = new Stack();
BinNode temp = root;
//入棧
while (temp != null)
{
if (temp != null)
stack
temp = temp
}
//出棧
while (stack
{
BinNode lastvisit = temp;
temp = (BinNode)stack
if (temp
{
Console
}
else if (temp
{
stack
temp = temp
stack
while (temp != null)
{
if (temp
stack
temp = temp
}
}
}
}
//中序遍歷
static void InOrder(BinNode root)
{
Stack stack = new Stack();
BinNode temp = root;
//入棧
while (temp != null)
{
if (temp != null)
stack
temp = temp
}
//出棧
while (stack
{
temp = (BinNode)stack
Console
if (temp
{
temp = temp
stack
while (temp != null)
{
if (temp
stack
temp = temp
}
}
}
}
?
?
在二叉樹中找出和為某一值的所有路徑
算法思想
為此
此外
static void FindBinNode(BinNode root
{
if (root == null)
return;
stack
//Leaf
if (root
{
if (root
{
Stack tempStack = new Stack();
while (stack
{
tempStack
}
while (tempStack
{
Console
stack
}
Console
}
}
if (root
FindBinNode(root
if (root
FindBinNode(root
stack
}
?
?
?
?
怎樣編寫一個程序 把一個有序整數數組放到二叉樹中?
算法思想
//// arr[
//// arr[
//// arr[
相應編碼如下
public static void InsertArrayIntoTree(int[] arr
{
root = new BinNode(arr[pos]
root
//if Left value less than arr length
if (pos *
{
return;
}
else
{
InsertArrayIntoTree(arr
}
//if Right value less than arr length
if (pos *
{
return;
}
else
{
root
InsertArrayIntoTree(arr
}
}
?
?
判斷整數序列是不是二叉搜索樹的後序遍歷結果
比如
算法思想
由於不能使用動態數組
public static bool VerifyArrayOfBST(int[] arr
{
if (arr == null || arr
{
return false;
}
int root = arr[length + start
int i = start;
for (; i < length
{
if (arr[i] >= root)
break;
}
int j = i;
for (; j < length
{
if (arr[j] < root)
return false;
}
bool left = true;
if (i > start)
{
left = VerifyArrayOfBST(arr
}
bool right = true;
if (j > i)
{
right = VerifyArrayOfBST(arr
}
return left && right;
}
?
?
求二叉樹的鏡像
算法
static void PreOrder(ref BinNode root)
{
if (root == null)
return;
//visit current node
BinNode temp = root
root
root
PreOrder(ref root
PreOrder(ref root
}
?
?
算法
static void PreOrder
{
if (root == null)
return;
Stack stack = new Stack();
stack
while (stack
{
//visit current node
BinNode temp = root
root
root
if (root
stack
if (root
stack
}
}
?
?
一棵排序二叉樹(即二叉搜索樹BST) 令 f=(最大值+最小值)/ 設計一個算法 找出距離f值最近 大於f值的結點 復雜度如果是O(n )則不得分
算法思想
static BinNode Find(BinNode root)
{
BinNode min = FindMinNode(root);
BinNode max = FindMaxNode(root);
double find = (double)(min
return FindNode(root
}
?
?
static BinNode FindMinNode(BinNode root)
{
BinNode min = root;
while (min
{
min = min
}
return min;
}
static BinNode FindMaxNode(BinNode root)
{
BinNode max = root;
while (max
{
max = max
}
return max;
}
遞歸尋找BST的節點
static BinNode FindNode(BinNode root
{
//如果小於相等
if (root
{
if (root
return root;
BinNode find = FindNode(root
//不一定找得到
return find
root : find;
}
//如果大於
else //temp
{
if (root
return root;
BinNode find = FindNode(root
//不一定找得到
return find
root : find;
}
}
?
?
?
把二叉搜索樹轉變成排序的雙向鏈表 如
////
////
////
////
轉變為Link
算法思想
static void ConvertNodeToLink(BinNode root
{
if (root == null)
return;
BinNode temp = root;
if (temp
ConvertNodeToLink(temp
//visit current node
link
link = link
if (temp
ConvertNodeToLink(temp
}
?
?
但是我們發現
static DoubleLink ReverseDoubleLink(BinNode root
{
ConvertNodeToLink(root
DoubleLink temp = link;
while (temp
{
temp = temp
}
return temp;
}
這麼寫有點蠢
?
?
算法
此外
代碼如下所示
link
link = link
那麼
為此
link
link = link
這樣
算法代碼如下所示
static void ConvertNodeToLink
{
if (root == null)
return;
BinNode temp = root;
if (temp
ConvertNodeToLink
//visit current node
link
link = link
if (temp
ConvertNodeToLink
}
?
?
以下算法屬於二叉樹的基本概念
?
?
玩二叉樹
唉
From:http://tw.wingwit.com/Article/program/sjjg/201404/30577.html