软件工程第四次作业

这个作业属于软件工程 https://edu.cnblogs.com/campus/zswxy/2018SE
这个作业要求实现排序算法和和二叉树的先,中,后以及层次遍历 https://edu.cnblogs.com/campus/zswxy/2018SE/homework/11406
这个作业的目标是学习数据结构 学会一些排序算法和理解二叉数
其他参考文献 ...

一.给定一个序列,每次询问第l个数到第r个数中第k大的数.

解题思路

1.实现思路
(本题的核心就是排序,考虑到时间复杂度,我选择了比较快的快速排序算法。)
先从给定的序列中截取所需的询问序列,而询问序列的长度就是r-l+1,再排序,排序后 这个序列中第k大的数就是r-l+1-k(序列的长度-k)
2.具体实现
(1)考虑到空间复杂度,不使用过多中间变量,设置数组arr存储序列,arrCopy作为询问序列的中间数组,一个二维数组marks存储m个询问序列的条件l,r,k 。
(2)先用javaScanner类获得键盘输入数据,并将序列值存入数组arr,询问序列条件存入二维数组marks;
(3)再在for循环中根据marks中的条件依次从arr中截取出询问序列并排序,再输出第k大的值;

解题代码

`
public class test {

private static int[] arr;
private static int[][] marks;
private static int[] arrCopy;
public static void main(String args[]){
	Scanner sc=new Scanner(System.in);
	System.out.println("请按本题规范格式输入数据");
	//1.获取序列长度,并创建一个数组存储该序列
	arr=new int[sc.nextInt()];
	sc.nextLine();//消除空格
	//2.将序列填进数组
	for(int i=0;i<arr.length;i++){
		arr[i]=sc.nextInt();
	}
	sc.nextLine();//消除空格
	//3.获取询问个数,并创建m行3列的二维数组
	marks=new int[sc.nextInt()][3];
	//4.获取多个询问序列
	for(int i=0;i<marks.length;i++){
		if(i==(marks.length-1)){
		}else{
			sc.nextLine();//消除空格
		}
		for(int j=0;j<3;j++){
			marks[i][j]=sc.nextInt();
		}
		if(marks[i][2]>(marks[i][1]-marks[i][0]+1)){
			System.out.println("输入格式错误");
			return;
		}
	}
	//5.根据约束条件copy从序列中copy一个数组
	for(int i=0;i<marks.length;i++){
	arrCopy=new int[marks[i][1]-marks[i][0]+1];
	System.arraycopy(arr,marks[i][0]-1, arrCopy,0, marks[i][1]-marks[i][0]+1);
	//6.排序,并查找k大的数输出
	quickSort(arrCopy,0,arrCopy.length-1);
	System.out.println(arrCopy[marks[i][1]-marks[i][0]+1-marks[i][2]]);
	}
}
//快速排序
public static void quickSort(int[] arr, int left, int right) {
    if(left > right) {
        return;
    }
    // base中存放基准数
    int base = arr[left];
    int i = left, j = right;
    while(i != j) {
        // 从右边开始往左找,直到找到比base值小的数
        while(arr[j] >= base && i < j) {
            j--;
        }

        // 再从左往右边找,直到找到比base值大的数
        while(arr[i] <= base && i < j) {
            i++;
        }

        // 上面的循环结束表示找到了位置或者(i>=j)了,交换两个数在数组中的位置
        if(i < j) {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }

    // 基准数归位
    arr[left] = arr[i];
    arr[i] = base;

    // 递归排序
    quickSort(arr, left, i - 1);
    quickSort(arr, i + 1, right);
}

}
`

对数器

根据对数器的条件,我用Java自带的Arrays.sort()方法和自己实现的快速排序算法对比
`public class check {

public static void main(String[] args){
	int testtime =1000;
	int MaxSize =10;
	int MaxValue =1000;
	boolean isSucceed=true;
	int[] arr1;
	int[] arr2;
	int[] arr3;
	for(int i=1;i<=testtime;i++){
		arr1=getRedomArray(MaxSize,MaxValue);
		arr2=copyArray(arr1);
		arr3=copyArray(arr2);//如果失败则打印该样本
		systemSort(arr1);
		quickSort(arr2,0,arr2.length-1);
		if(!isEqual(arr1,arr2)){
			isSucceed=false;
			System.out.println(Arrays.toString(arr3));
			break;
		}
	}
	System.out.println(isSucceed?"该算法正确":"该算法不正确");
	int [] arr=getRedomArray(MaxSize,MaxValue);
	System.out.println(Arrays.toString(arr));
	quickSort(arr,0,arr.length-1);
	System.out.println(Arrays.toString(arr));
	
}
//数组复制
public static int[] copyArray(int[] arr1){
	int[] arr2=new int[arr1.length];
	System.arraycopy(arr1, 0, arr2, 0, arr1.length);
	return arr2;
}
//随机随机样本产生器
public static int[] getRedomArray(int MaxSize,int MaxValue){
	int[] temp=new int[(int) ((MaxSize+1)*Math.random())];
	for(int i=0;i<temp.length;i++){
		temp[i]=(int)((MaxValue+1)*Math.random()-(int)(MaxValue*Math.random()));
	}
	return temp;
}
//对比方法
public static boolean isEqual(int[] arr1,int[] arr2){
	if((arr1==null&&arr2!=null)||(arr1!=null&&arr2==null)){
		return false;
	}
	if(arr1==null&&arr2==null){
		return true;
	}
	if(arr1.length!=arr2.length){
		return false;
	}
	for(int i=0;i<arr1.length;i++){
		if(arr1[i]!=arr2[i]){
			return false;
		}
	}
	return true;
}
//系统排序
public static void systemSort(int[] arr){
	Arrays.sort(arr);
}
//快速排序
 public static void  quickSort(int[] arr, int low, int high) {
        if (low>=high){
        	return;
        }
        //找出基准值temp
        int index = getIndex(arr, low, high);
        //左排序
        quickSort(arr,0,index-1);
        //右排序
        quickSort(arr,index+1,high);
    }
 public static int getIndex(int[] arr, int low, int high) {
        int temp=arr[low];
        while (low<high){
            //右排序
            while (low<high&&arr[high]>=temp){
                //如果arr[high]>=temp,high--
                high--;
            }
            //把arr[high]的值赋给arr[low]
            arr[low]=arr[high];
            //左排序
            while (low<high&&arr[low]<temp){
                //如果arr[low]<temp,low++
                low++;
            }
            //把arr[low]的值赋给arr[high]
            arr[high]=arr[low];
        }
        //复位
        arr[low]=temp;
        return low;
    }

}`

二.实现二叉树的先,中,后及层次遍历.

解题思路

1.顾名思义,先序遍历就是先遍历根子树,后遍历左子树,再遍历右子树。
中序遍历就是先遍历左子树,后遍历根子树,再遍历右子树。
后序遍历就是先遍历左子树,后遍历右子树,再遍历根子树。
先中后序遍历用递归实现即可
2.层次遍历就依层遍历。
层次遍历需借助Java中队列LinkedListwhile循环来实现,先将根节点放入队列中,再取出根节点打印节点值,再依次放入该节点的左右节点,
每当前一层节点遍历完就从队列中取出,放入下层节点,循环遍历;

解题代码

`public class Main {

public static void main(String[] args) {
    /*
        作业要求:叉树的先、中、后 序遍历与层级遍历
        自己实现四个方法,main方法中调用,将结果打印到控制台
     */
    /*  二叉树的结构
                 A
                / \
               T   6
              /
             D
           /   \
          N     5
         / \    /
        B   4  1
             \
              9
     */ 
    Node root = into();
    // 先序遍历
    A(root);
    System.out.println();
    // 中序遍历
    B(root);
    System.out.println();
    // 后续遍历
    C(root);
    System.out.println();
    // 层级遍历
    D(root);

}
private static void visit(Node node){
	System.out.print(node.data);
}
private static void A(Node node) {
	if(node!=null){
		visit(node);
		A(node.l);
		A(node.r);
	}
    // TODO 先序遍历
}
private static void B(Node node) {
    // TODO 中序遍历
  	if(node!=null){
  		B(node.l);
		visit(node);
		B(node.r);
	}
}
private static void C(Node node) {
    // TODO 后续遍历
  	if(node!=null){
  		C(node.l);
		C(node.r);
		visit(node);
	}
}

private static void D(Node node) {
    // TODO 层级遍历
	if(node==null){
		return;
	}
	LinkedList<Node> queue=new LinkedList();
	Node temp;
	queue.offer(node);
	while(!queue.isEmpty()){
		temp=queue.poll();
		visit(temp);
		if(temp.l!=null){
			queue.offer(temp.l);
		}
		if(temp.r!=null){
			queue.offer(temp.r);
		}
	}
}

// 构建一颗树,返回根节点
private static Node into(){
    Node root = new Node("A");
    Node node1 = new Node("T");
    Node node2 = new Node("D");
    Node node3 = new Node("N");
    Node node4 = new Node("B");
    Node node5 = new Node("6");
    Node node6 = new Node("5");
    Node node7 = new Node("4");
    Node node8 = new Node("9");
    Node node9 = new Node("1");
    root.l = node1;
    node1.l = node2;
    node2.l = node3;
    node2.r = node6;
    node3.r = node7;
    node7.r = node8;
    node6.l = node9;
    node3.l = node4;
    root.r = node5;
    return root;
}

// 节点
static class Node{
    // 数据
    Object data;
    // 左孩子
    Node l;
    // 右孩子
    Node r;

    public Node(){} 
    public Object getDate(Node node){
    	return node.data;
    }
    public Node(Object data) {
        this.data = data;
        this.l = null;
        this.r = null;
    }

    public Node(Object data, Node l, Node r) {
        this.data = data;
        this.l = l;
        this.r = r;
    }
}

}
`

posted @ 2020-10-29 16:15  慕之情  阅读(87)  评论(0编辑  收藏  举报