算法补充 2011-9-12
?
設計一個算法將順序表L中所有小于0的整數放前半部分,大于等于0的整數放在后半部分
思路:從左側找出>0的元素,從右側找出<=0的元素,然后進行交換
static void Move(SqList &l) {int i=0,j=l.length-1;while(i<j){//position from left to rightwhile(i<j && l.elem[i]<0)i++;//position from right to leftwhile(i<j && l.elem[j]>=0)j--;//swapif(i<j){int temp=l.elem[i];l.elem[i]=l.elem[j];l.elem[j]=temp;}} }?
二叉樹的刪除
?
情況1:刪除沒有子節點的節點
即刪除6,7,8,9,2這些節點
執行第1步,查找節點如果current不為空則執行第2步
Node current = root;Node parent = root;boolean isLeftChild = true;while(current.iData != key) // search for node{parent = current;if(key < current.iData) // go left?{isLeftChild = true;current = current.leftChild;}else // or go right?{isLeftChild = false;current = current.rightChild;}if(current == null) // end of the line,return false; // didn't find it} // end while// found node to delete執行第2步,判斷左右節點均未空
// if no children, simply delete it if(current.leftChild==null &¤t.rightChild==null){if(current == root) // if root,root = null; // tree is emptyelse if(isLeftChild)parent.leftChild = null; // disconnectelse // from parentparent.rightChild = null;}情況2:有一個子節點的節點
第1步如情況1的第1步相同,還是先找到要刪除的節點.
執行步驟1和步驟4
if(current.rightChild==null)if(current == root)root = current.leftChild;else if(isLeftChild)parent.leftChild = current.leftChild;elseparent.rightChild = current.leftChild;執行步驟2和步驟4
// if no left child, replace with right subtree if(current.leftChild==null)if(current == root)root = current.rightChild;else if(isLeftChild)parent.leftChild = current.rightChild;elseparent.rightChild = current.rightChild;情況3:刪除有兩個子節點的節點
鋪墊:
1.查找二叉排序樹的最大值和最小值
因為二叉樹的的節點總是大于左節點,小于右節點的,所以順著左節點總是能找到最小值,同理順著右節點總是能找到最大值
public Node getMin() { Node current = root; Node last; while(current!=null) {last=current;current = current.leftChild; } return last; } public Node getMax() { Node current = root; Node last; while(current!=null) {last=current;current = current.rightChild; } return last; }2.二叉排序樹的中序遍歷
如上圖
二叉排序樹的中序遍歷的值是一個升序排列,以上結果為15,20,25,30,50,60,70
?
尋找具有有兩個子節點的節點的替補節點
如要刪除該節點,要么被代替的節點需要具備以下特征:
如果無法滿足以上兩點,情況將變的更加復雜.
如要刪除節點20,那么節點30則是最佳替補(這里如果有個節點25則更加說明這個情況).
節點25比15大,比30小.
中序后繼:由于25在20后面,則成25為節點20的后繼.所以當遇到要刪除有兩個節點的節點時,首要目標就是找到該節點的后繼節點,以上的鋪墊1內容就是為這里準備的。查找后繼節點規則:
以下代碼體現了以上2個步驟
private Node getSuccessor(Node delNode){Node successorParent = delNode;Node successor = delNode;Node current = delNode.rightChild; // go to right childwhile(current != null) // until no more{ // left children,successorParent = successor;successor = current;current = current.leftChild; // go to left child}return successor;}刪除中序后繼節點
找到中序后繼后,還要處理一些事情.來考慮一個中序后繼的一些特點:
所以要按照情況2只有右節點的原則處理該右繼節點
鏈接中序后繼的右節點
即要刪除的節點的右節點變成了中序后繼節點的右節點了
所以在getSuccessor方法中while循環結束后,還需要做以下處理
if(successor != delNode.rightChild) // right child,{ // make connectionssuccessorParent.leftChild = successor.rightChild;successor.rightChild = delNode.rightChild;}鏈接中序后繼的左節點
Node successor = getSuccessor(current);// connect parent of current to successor instead if(current == root)root = successor; else if(isLeftChild)parent.leftChild = successor; elseparent.rightChild = successor;// connect successor to current's left child successor.leftChild = current.leftChild;可以看到刪除一個后繼的動作相當的復雜
完整刪除代碼示例(來自Java數據結構和算法)
public boolean delete(int key) // delete node with given key{ // (assumes non-empty list)Node current = root;Node parent = root;boolean isLeftChild = true;while(current.iData != key) // search for node{parent = current;if(key < current.iData) // go left?{isLeftChild = true;current = current.leftChild;}else // or go right?{isLeftChild = false;current = current.rightChild;}if(current == null) // end of the line,return false; // didn't find it} // end while// found node to delete// if no children, simply delete itif(current.leftChild==null &¤t.rightChild==null){if(current == root) // if root,root = null; // tree is emptyelse if(isLeftChild)parent.leftChild = null; // disconnectelse // from parentparent.rightChild = null;}// if no right child, replace with left subtreeelse if(current.rightChild==null)if(current == root)root = current.leftChild;else if(isLeftChild)parent.leftChild = current.leftChild;elseparent.rightChild = current.leftChild;// if no left child, replace with right subtreeelse if(current.leftChild==null)if(current == root)root = current.rightChild;else if(isLeftChild)parent.leftChild = current.rightChild;elseparent.rightChild = current.rightChild;else // two children, so replace with inorder successor{// get successor of node to delete (current)Node successor = getSuccessor(current);// connect parent of current to successor insteadif(current == root)root = successor;else if(isLeftChild)parent.leftChild = successor;elseparent.rightChild = successor;// connect successor to current's left childsuccessor.leftChild = current.leftChild;} // end else two children// (successor cannot have a left child)return true; // success} // end delete() // -------------------------------------------------------------// returns node with next-highest value after delNode// goes to right child, then right child's left descendentsprivate Node getSuccessor(Node delNode){Node successorParent = delNode;Node successor = delNode;Node current = delNode.rightChild; // go to right childwhile(current != null) // until no more{ // left children,successorParent = successor;successor = current;current = current.leftChild; // go to left child}// if successor notif(successor != delNode.rightChild) // right child,{ // make connectionssuccessorParent.leftChild = successor.rightChild;successor.rightChild = delNode.rightChild;}return successor;}轉載于:https://www.cnblogs.com/Clingingboy/archive/2011/09/12/2173981.html
總結
以上是生活随笔為你收集整理的算法补充 2011-9-12的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《OpenCV算法精解——基于Pytho
- 下一篇: 如何使用cmd查看本机IP地址