数据结构与算法

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));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值