static class TreeNode{//二叉树结点 public TreeNode(TreeNode l, TreeNode r, int data){ left = l; right = r; this.data = data; } TreeNode left; TreeNode right; boolean hasLeftChild;//用于对二叉树线索化,为false时表示left指向上一个结点 boolean hasRightChild;//为false时表示right指向下一个结点 int data; } public static void demo19(){//测试deleteFromSortedTree是否能正确删除排序树中的结点 TreeNode root = createSortedTree(); StringBuilder sb = new StringBuilder(200); inOrderTraverse(sb,root); println(sb.toString()); for(int i=9; i<15; i++){ root = deleteFromSortedTree(root,i); } sb.delete(0,sb.length()); inOrderTraverse(sb,root); println(sb.toString()); } public static void demo18(){//二叉排序树例子 TreeNode root = createSortedTree(); StringBuilder sb = new StringBuilder(200); inOrderTraverse(sb, root); sb.delete(sb.length()-1, sb.length()); println(sb.toString()); } public static void inOrderTraverse(StringBuilder sb, TreeNode node){//中序遍历排序二叉树,以得到从小到大的排列 if(node == null) return; inOrderTraverse(sb, node.left); sb.append(node.data + ","); inOrderTraverse(sb,node.right); } public static TreeNode createSortedTree(){//创建一个排序二叉树 TreeNode root = new TreeNode(null,null,50); Random rand = new Random(); for(int i=0; i<100; i++){//创建100个结点 TreeNode n = new TreeNode(null,null,rand.nextInt(100)); insertToSortedTree(root,n); } return root; } public static void insertToSortedTree(TreeNode root, TreeNode n){//将结点逐个插入排序二叉树中 if(n.data<root.data){ if(root.left==null){ root.left = n; return; } insertToSortedTree(root.left,n); }else{ if(root.right==null){ root.right = n; return; } insertToSortedTree(root.right,n); } } /** * * @param root * @param i * @return new root node */ public static TreeNode deleteFromSortedTree(TreeNode root, int i){ TreeNode parent = null; TreeNode node = root; boolean isLeft=false; while(true){ if(node.data == i){ if(parent != null){ if(node.right==null && node.left==null){ if(isLeft) parent.left = null; else parent.right = null; }else if(node.right!=null && node.left!=null){ TreeNode n = node.left; TreeNode p = node; while(n.right!=null){ p = n; n = n.right; } node.data = n.data; if(p==node) p.left = n.left; else p.right = n.left; }else if(node.right != null){ if(isLeft) parent.left = node.right; else parent.right = node.right; }else if(node.left != null){ if(isLeft) parent.left = node.left; else parent.right = node.left; } }else{ if(node.right==null && node.left==null){ return null; }else if(node.right!=null && node.left!=null){ TreeNode n = node.left; TreeNode p = node; while(n.right!=null){ p = n; n = n.right; } node.data = n.data; if(p==node) p.left = n.left; else p.right = n.left; }else if(node.right != null){ return node.right; }else if(node.left != null){ return node.left; } } return root; }else if(i<node.data){ if(node.left==null) return root; parent = node; node = node.left; isLeft = true; }else{ if(node.right==null) return root; parent = node; node = node.right; isLeft = false; } } } public static void demo17(){//层次遍历 TreeNode node = createHierarchyTree(); hierarcalTraverse(node); } public static TreeNode createHierarchyTree(){//使用层次遍历的方法创建二叉树 LinkedList<TreeNode> queue = new LinkedList(); data = 1; TreeNode root = new TreeNode(null,null,data++); queue.offer(root); TreeNode node; while((node=queue.poll()) != null){ if(data<=100){//只添加100个元素,值从1到100 node.left = new TreeNode(null,null,data++); queue.offer(node.left); } if(data<=100){ node.right = new TreeNode(null,null,data++); queue.offer(node.right); } } return root; } public static void hierarcalTraverse(TreeNode root){//层次遍历 LinkedList<TreeNode> queue = new LinkedList(); queue.offer(root); TreeNode node; StringBuilder sb = new StringBuilder(200); while((node=queue.poll()) != null){ sb.append(node.data + ","); if(node.left != null) queue.offer(node.left); if(node.right != null) queue.offer(node.right); } sb.delete(sb.length()-1, sb.length()); println(sb.toString()); } public static void demo16(){//先序创建一个二叉树,再线索化,并进行先序遍历 prev = null; data = 1; double c = Math.log(100)/Math.log(2); println("level: " + c); TreeNode node = preOrder(0,null,false); preOrderThread(node);//对先序二叉树进行线索化 // StringBuilder sb = new StringBuilder(200); // preOrderVisit(sb, node); StringBuilder sb1 = new StringBuilder(200); TreeNode n = node; sb1.append(node.data + ","); while((n=preOrderGetNextNode(n)) != null){//遍历先序线索树 sb1.append(n.data + ","); } // sb.delete(sb.length()-1, sb.length()); sb1.delete(sb1.length()-1, sb1.length()); // println(sb.toString()); println(sb1.toString()); } public static void demo15(){//先序创建一个二叉树,并进行先序访问 data = 1; double c = Math.log(100)/Math.log(2); println("level: " + c); TreeNode node = preOrder(0,null,false); StringBuilder sb = new StringBuilder(200); preOrderVisit(sb, node); println(sb.toString()); } static int data = 1; public static TreeNode preOrder(int level,TreeNode parent,boolean isLeftChild){//先序创建一个二叉树。该树如果使用先序访问,出来的数据就会是有序的 if(data >100) return null; TreeNode node = new TreeNode(null,null,data++); if(parent != null){ if(isLeftChild) parent.left = node; else parent.right = node; } if(level<(Math.log(100)/Math.log(2)-1)){//按丰满树100结点的深度来确定树的深度 preOrder(level+1,node,true); preOrder(level+1, node,false); } return node; } static TreeNode prev;//创建一个全局的记录上一个被访问的结点 public static void preOrderThread(TreeNode node){//建立先序线索二叉树 if(prev != null && !prev.hasRightChild)//将上一个结点与该结点建立线索。使上一个被访问的结点的next指向该结点 prev.right = node; if(node.left==null){ node.hasLeftChild = false; node.left = prev;//将上一个结点与该结点建立线索。使该结点的prev指向上一个被访问的结点 }else { node.hasLeftChild = true; } if(node.right==null){//因为在访问左结点时会使用到hasRightChild这个属性,所以要在这里就确定它的值 node.hasRightChild = false; }else { node.hasRightChild = true; } prev = node;//该结点已被访问了,把prev指向该结点 if(node.hasLeftChild) preOrderThread(node.left); if(node.hasRightChild) preOrderThread(node.right); } public static TreeNode preOrderGetNextNode(TreeNode node){//获取先序线索树的中node结点的下一个结点 if(!node.hasRightChild) return node.right; else{ if(node.hasLeftChild) return node.left; else return node.right; } } public static void preOrderVisit(StringBuilder sb, TreeNode node){//先序访问树 if(node == null) return; sb.append(node.data+","); preOrderVisit(sb,node.left); preOrderVisit(sb,node.right); } static class LinkedQueue{ Node head; Node tail; public void offer(Node n){ if(head==null){ head = n; tail = n; }else{ tail.next = n; tail = n; } } public Node poll(){ if(head == null) return null; Node n = null; if(head==tail){ n = head; head = null; tail = null; }else{ n = head; head = head.next; } return n; } } public static void demo14(){ LinkedQueue queue = new LinkedQueue(); for(int i=0; i<50; i++){ queue.offer(new Node(null,i)); } StringBuilder sb = new StringBuilder(200); while(true){ Node n = queue.poll(); if(n != null){ sb.append(n.value+","); }else break; } for(int j=50; j<100; j++){ queue.offer(new Node(null,j)); } while(true){ Node n = queue.poll(); if(n != null){ sb.append(n.value+","); }else break; } sb.delete(sb.length()-1,sb.length()); println(sb.toString()); } static class SequenceQueue{//顺序队列 int[] data = new int[70]; int front;//指向下一个被获取的元素(满足以下条件时该意义无效:如果front==rear时,意味着队列为空,此时front指向的位置的数据是没有有效数据的) int rear;//指向下一个元素要存放的位置(满足以下条件时,该意义无效:如果rear-front=maxSize时,意味着队列为满,此时rear指向的位置存放的数据是下一个被获取的元素) public boolean offer(int i){ if(rear-front==data.length) return false; data[rear++%data.length] = i; return true; } public int poll(){ if(rear==front) throw new NoSuchElementException(); return data[front++%data.length]; } } public static void demo13(){//检验顺序队列 SequenceQueue queue = new SequenceQueue(); StringBuilder sb = new StringBuilder(200); for(int i=0; i<100; i++){ if(!queue.offer(i)){ for(int j=0; j<40; j++){ sb.append(queue.poll() + ","); } queue.offer(i); } } try{ while(true){ sb.append(queue.poll() + ","); } }catch(Exception e){ } sb.delete(sb.length()-1, sb.length()); println(sb.toString()); } static class LinkedStack{ Node top = new Node(null,-1); public void push(Node n){ if(n==null) return; n.next = top.next; top.next = n; } public Node pop(){ if(top.next==null) return null; Node n = top.next; top.next = n.next; return n; } } public static void demo12(){ LinkedStack s = new LinkedStack(); for(int i=0; i<100; i++){ s.push(new Node(null,i)); } StringBuilder sb = new StringBuilder(200); while(true){ Node n = s.pop(); if(n==null) break; sb.append(n.value + ","); } sb.delete(sb.length()-1,sb.length()); println(sb.toString()); } static class MyStack{//顺序栈 int[] data = new int[1024]; int top = -1; public boolean offer(int i){ if(top == data.length-1) return false; data[++top] = i; return true; } public int pop(){ if(top<0) throw new NoSuchElementException(); return data[top--]; } } public static void demo11(){//检验顺序栈 MyStack s = new MyStack(); for(int i=0; i<100; i++){ s.offer(i); } StringBuilder sb = new StringBuilder(200); try{ while(true){ sb.append(s.pop() + ","); } }catch(Exception e){ } sb.delete(sb.length()-1,sb.length()); println(sb.toString()); } static class Node { Node(Node next, int value){ this.next = next; this.value = value; } Node(Node next, Node prev, int value){ this(next,value); this.prev = prev; } Node next; Node prev; int value; public String toString(){//for demo7 if(next != null) return value + " -> " + next.toString(); else return String.valueOf(value); } public String prevToString(){ if(prev != null){ return value + " -> " + prev.prevToString(); }else{ return String.valueOf(value); } } } public static void demo10(){//创建循环双向链表 Node head = new Node(null,null,-1); for(int i=0; i<100; i++){ Node node; if(head.next == null){ node = new Node(null,null, i); node.next = node; node.prev = node; }else{ node = new Node(head.next,head.next.prev,i); node.next.prev = node; node.prev.next = node; } head.next = node; } Node n = head.next; StringBuilder sb = new StringBuilder(600); while(n.next != head.next){ sb.append(n.value + " -> "); n = n.next; } sb.append(String.valueOf(n.value)); println(sb.toString()); } public static void demo9(){//创建双向链表 Node head = new Node(null, null,-1); Node tail = null; for(int i=0; i<100; i++){ Node node = new Node(head.next,head,i); if(head.next != null) head.next.prev = node; head.next = node; if(i==0) tail = node; } // println(head.next.toString()); println(tail.prevToString()); } public static Node demo8(){//创建单向循环链表 Node head = new Node(null,-1); for(int i=0; i<100; i++){ if(head.next == null){ Node node = new Node(null, i); node.next = node; head.next = node; }else{ Node node1 = new Node(head.next.next,i); head.next.next = node1; } } StringBuilder sb = new StringBuilder(600); Node n = head.next; if(n == null) return head; while(!n.next.equals(head.next)){ sb.append(n.value + " -> "); n = n.next; } sb.append(String.valueOf(n.value)); println(sb.toString()); return head; } public static Node demo7(){//创建一个单向链表 Node head = new Node(null,-1); for(int i=0; i<100; i++){ Node node= new Node(head.next,i); head.next = node; } println(head.next.toString()); return head; } static int[] array1 = {5,64,41,89,43,2,16,5,1,32,56,549,8,4,13,2,21,0,2,1,2,6,404,3,37,2,46,49,0,4,33,74,97,127,17,337,97,21,79,31,775,82,12,56,46,79,80,0,2,13,4,69,8,2,64}; public static void demo6(){//选择排序类之堆排序 int[] array = new int[array1.length]; System.arraycopy(array1,0,array,0,array1.length); for(int i=array.length/2-1; i>=0; i--){//为整个array建立大顶堆,记得要从最后一个父节点开始建立大顶堆 adjustSort(i,array.length-1,array); } //利用已有的大顶堆排序 for(int j=array.length-1; j>0; j--){ int temp = array[0]; array[0] = array[j]; array[j] = temp; adjustSort(0,j-1,array); } println(Arrays.toString(array)); } public static void adjustSort(int node,int maxIndex, int[] arr){//为父节点node建立大顶堆 for(int childIndex=node*2+1; childIndex<=maxIndex; childIndex=childIndex*2+1){ if(childIndex+1<=maxIndex && arr[childIndex+1] > arr[childIndex]) childIndex++; if(arr[childIndex]>arr[node]){ int temp = arr[node]; arr[node] = arr[childIndex]; arr[childIndex] = temp; node = childIndex; }else break; } } public static void demo5(){//选择排序类之直接选择排序 int[] arr = new int[array1.length]; System.arraycopy(array1,0,arr,0,array1.length); for(int i=0; i<arr.length-1; i++){ int min = i; for(int j=i+1; j<arr.length; j++){ if(arr[j]<arr[min]) min = j; } int temp = arr[i]; arr[i] = arr[min]; arr[min] = temp; } println(Arrays.toString(arr)); } public static void demo4(){//交换类排序之快速排序 int[] array = new int[array1.length]; System.arraycopy(array1,0,array,0,array1.length); quickSort(array,0,array.length-1); println(Arrays.toString(array)); } public static void quickSort(int[] arr,int right,int left){//交换类排序之快速排序 int low=right,high=left; int key=arr[low];//首先空出了low位置,这个key就是各元素放在左边还是右边的依据 if(high > low) {//若是high==low,则说明上一次递归中的key的这一边只有一个元素,递归可以结束了 while (high > low) { while (high > low && arr[high] >= key) { high--; } arr[low] = arr[high];//空出high位置 while (high > low && arr[low] <= key) { low++; } arr[high] = arr[low];//空出low位置 } arr[low] = key;//最终确定key的位置 quickSort(arr, right, low - 1);//当right==low-1,那么证明key右边只有一个元素,这个递归是不会执行了 quickSort(arr, low+1, left);//与上面同理 } } public static void demo3(){//交换类排序之冒泡排序 int[] arr = new int[array1.length]; System.arraycopy(array1,0,arr,0,array1.length); for(int i=arr.length-1; i>0; i--){ int flag = 0;//如果一趟下来没有发生交换说明是有序的,不用继续排序了。 for(int j=0; j<i; j++){ if(arr[j] > arr[j+1]){ flag = 1; int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } if(flag == 0) break; } println(Arrays.toString(arr)); } public static void demo2(){//shell sort;直接插入排序之希尔排序 int[] arr = new int[array1.length]; System.arraycopy(array1,0,arr,0,array1.length); int gap = arr.length/2; while(gap>=1){ for(int i=gap;i<arr.length;i++){ int temp = arr[i]; int j; for(j=i-gap; j>=0&&temp<arr[j]; j-=gap){ arr[j+gap] = arr[j]; } arr[j+gap] = temp; } gap /= 2; } println(Arrays.toString(arr)); } public static void demo1(){//插入类排序之二分法排序 int[] array = new int[array1.length]; System.arraycopy(array1,0,array,0,array1.length); int temp; for(int i=1; i<array.length; i++){ temp = array[i]; int low=0,high=i-1; while(low<=high){ int mid = (low+high)/2; if(temp>array[mid]) low = mid+1; else high = mid-1; } //统一后移 for(int j=i-1; j>=low; j--){ array[j+1] = array[j]; } array[low] = temp; } println(Arrays.toString(array)); } public static void demo0(){//插入类排序之直接插入排序 int[] array = new int[array1.length]; System.arraycopy(array1,0,array,0,array.length); int temp; for(int i=1; i<array.length; i++){ temp = array[i]; int j = i-1; while(j>=0 && temp<array[j]){ array[j+1] = array[j]; j--; } array[++j] = temp; } println(Arrays.toString(array)); }
数据结构与算法
最新推荐文章于 2022-09-05 15:00:33 发布