2. 常见小算法(排序以及画三角)

本文详细介绍了四种经典的排序算法:冒泡排序、选择排序、插入排序和快速排序,包括它们的原理、时间复杂度及Java实现。此外,还展示了如何绘制不同类型的三角形图案,如倒等腰三角形、正等腰三角形、直角三角形和菱形。最后,文章还提及了字符串反转的实现方法。这些内容涵盖了基础算法和数据结构的应用。
摘要由CSDN通过智能技术生成

一、查找

1. 冒泡排序

原理:比较两个相邻的元素,将值大的元素交换至右端。

用时间复杂度来说:

1.如果我们的数据正序,只需要走一趟即可完成排序。所需的比较次数C和记录移动次数M均达到最小值,即:Cmin=n-1;Mmin=0;所以,冒泡排序最好的时间复杂度为O(n)。

2.如果很不幸我们的数据是反序的,则需要进行n-1趟排序。每趟排序要进行n-i次比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:img

冒泡排序的最坏时间复杂度为:O(n2) 。

综上所述:冒泡排序总的平均时间复杂度为:O(n2) 。

BubbleSort

代码实现:

public class BubbleSort {
    public static void main(String[] args) {
        int arr[] = {2,3,1,9,4,7,6};
        int temp = 0;
        System.out.println("排序前的数组:");
        for (int num1 : arr) {
            System.out.print(num1+" ");
        }

        // 排序
        for (int i = 0; i < arr.length - 1; i++) { // 外层循环控制循环次数
            for (int j = 0; j < arr.length - 1 - i; j++) { // 内存循环控制每一趟的排序
                if (arr[j] > arr[j+1]){
                    temp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                }
            }
        }

        System.out.println();

        System.out.println("排序后的数组:");
        for (int num2 : arr) {
            System.out.print(num2+" ");
        }
    }
}

2. 选择排序

原理:简单选择排序是最简单直观的一种算法,每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。

  1. 从待排序列中选出最小(或最大)的一个元素,记录其下标(数组)的位置;
  2. 将记录的下标值与待排序列的第一个元素进行交换;
  3. 以此类推,直到全部待排序列的元素排完。

SelectionSort

选择排序是不稳定的排序方法。

时间复杂度:O(n^2)。

public class SelectionSort {
    public static void main(String[] args) {
        int[] arr = {43, 21, 65, 23, 65, 33, 21, 12, 43, 54};

        System.out.println("排序前的数组:");
        for (int num1 : arr) {
            System.out.print(num1 + " ");
        }

        System.out.println();

        System.out.println("排序后的数组:");
        selectionSort(arr);
        for (int num2 : arr) {
            System.out.print(num2 + " ");
        }
    }

    private static void selectionSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int min = i;
            for (int j = i+1; j < arr.length; j++) {
                if (arr[min] > arr[j]) {
                    min = j;
                }
            }
            if (min != i){
                int temp = arr[i];
                arr[i] = arr[min];
                arr[min] = temp;
            }
        }
    }
}

3. 插入排序

  1. 从数组第一个元素开始(0下标),该元素可以认为已经被排序;
  2. 取出待排序列中第一个元素,然后从“有序”序列中,从后往前扫描;
  3. 如果该元素(有序序列)大于待插入元素(待排序列),将该元素后移一个位置;
  4. 重复步骤3,直到找到“有序序列”中某一元素小于或等于“待插入元素”的位置;
  5. 将待插入元素插入到该元素(有序序列)后面(i+1)的位置上;
  6. 重复步骤2~5,直到待排序列中没有元素。

直接插入排序的时间复杂度为 o(n^2)。

InsertSort

public class InsertSort {
    public static void main(String[] args) {
        int[] arr = {5, 1, 7, 3, 1, 6, 9, 4};

        insert(arr);

        for (int i : arr) {
            System.out.print(i + " ");
        }
    }

    private static void insert(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int key = i-1;
            int value = arr[i];
            while (key >= 0 && arr[key] > value) {
                arr[key+1] = arr[key];
                key--;
            }
            arr[key+1] = value;
        }
    }
}

4. 二分查找

二分查找,是一种效率较高的查找方法,查找时要求表中的节点按关键字的大小排序,并且要求线性表顺序存储。

基本原理:

前提:数组是升序排列

首先将要找到的元素key与数组的中间元素比较

1、如果key小于中间元素,只需要在数组的前一半元素中继续查找

2、如果key和中间元素相等,匹配成功,查找结束

3、如果key大于中间元素,只需要在数组的后一半元素中继续查找

二分查找-案例

public class BinarySort {
    public static void main(String[] args) {
        int[] arr = {6, 12, 33, 87, 90, 97, 108, 561};

        binary1(arr, 90);
        for (int i : arr) {
            System.out.print(i + " ");
        }

        binSearch_2(90, arr, 0, arr.length - 1);
        for (int i : arr) {
            System.out.print(i + " ");
        }

    }

    //基本二分查找
    private static int binary1(int[] arr, int key) {
        int low = 0;
        int high = arr.length - 1;
        while (low <= high) { // 注意
            int mid = (low + high) / 2;
            if (arr[mid] == key)
                return mid;
            else if (arr[mid] < key)
                low = mid + 1; // 注意
            else if (arr[mid] > key)
                high = mid - 1; // 注意
        }
        return -1;
    }

    /**
	 * 使用递归的二分查找
	 *title:recursionBinarySearch
	 *@param arr 有序数组
	 *@param key 待查找关键字
	 *@return 找到的位置
	 */
	public static int recursionBinarySearch(int[] arr,int key,int low,int high){
		
		if(key < arr[low] || key > arr[high] || low > high){
			return -1;				
		}
		
		int middle = (low + high) / 2;			//初始中间位置
		if(arr[middle] > key){
			//比关键字大则关键字在左区域
			return recursionBinarySearch(arr, key, low, middle - 1);
		}else if(arr[middle] < key){
			//比关键字小则关键字在右区域
			return recursionBinarySearch(arr, key, middle + 1, high);
		}else {
			return middle;
		}		
	}

5. 快速排序

快速排序是由冒泡排序改进而得到的,是一种分区交换排序方法。

思想如下: 一趟快速排序采用从两头向中间扫描的方法,同时交换与基准记录逆序的记录。

1.选定Pivot中心轴

2.将大于Pivot的数字放到Pivot的右边

3.将小于Pivot的数字放到Pivot的左边

4.分别对左右子序列重复前三步

图解:

在这里插入图片描述

void QuickSort(int arr[],int L,int R){
    if(L > R){
        return;
    }
    int left = L;
    int Right = R;
    int poivt = arr[left];
    while (left < right){
        while (left < right && arr[right] >= poivt){
            right --;
        }
        if (left < right){
            arr[left] = arr[right];
        }
        while (left < right && arr[left] <= poivt){
            left ++;
        }
        if (left < right){
            arr[right] = arr[left];
        }
        if (left >= right){
            arr[left] = poivt;
        }
    }
    QuickSort(arr,L,right - 1);
    QuickSort(arr,right + 1,R); 
}

二、画三角

1. 倒等腰三角形

    //	倒等腰三角形
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < i; j++) {
                System.out.print(" ");
            }
            for (int j = 1; j < 2 * (5 - i); j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }

2. 正等腰三角

    @Test
    // 正等腰三角
    public void two(){
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < (5-i); j++) {
                System.out.print(" ");
            }
            for (int j = 0; j < i; j++) {
                System.out.print("*");
            }
            for (int j = 1; j < i; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }

3. 直角三角

   @Test
  
    public void two(){
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < (10-i); j++) {
                System.out.print(" ");
            }
            for (int j = 0; j < i; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

4. 菱形

    public void two() {
        for (int i = 0; i < 3; i++) {//上面的正等腰 少一行
            for (int j = 1; j < (4 - i); j++) {//每一行画空格的数量
                System.out.print(" ");
            }
            for (int j = 0; j <= 2 * i; j++) {//每一行画星星的数量
                System.out.print("*");
            }
            System.out.println();
        }
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < i; j++) {//每一行空格的数量
                System.out.print(" ");
            }
            for (int j = 1; j < 2 * (4 - i); j++) {//每一行画星星的数量
                System.out.print("*");
            }
            System.out.println();
        }
    }

5. 九九乘法表

    @Test
    //
    public void two() {
        for (int i = 1; i < 10; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print(j+"*"+i+"="+i*j+" ");
            }
            System.out.println();
        }
    }

三、其他

1.字符串反转

public class StringReverse {
    public static void main(String[] args) {
        //字符串反转
        String s = "hello world";
        String reserve = new StringBuffer(s).reverse().toString();
        System.out.println(s);
        System.out.println(reserve);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值