简单数据结构算法

这篇博客涵盖了多种排序算法,包括二分查找、合并有序数组、简单选择排序、快速排序和冒泡排序。同时深入讨论了直接插入排序与希尔排序的区别,并介绍了如何找到单词的变位词。此外,还讲解了递归的概念,通过递归求和、计算阶乘以及解决河内塔问题来展示递归的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有序列表二分查找

public boolean binarySearch(List<Integer> numbers, int value) {

    if (numbers.size() == 0 || numbers.isEmpty()) {
        return false;
    }

    int m = numbers.size() / 2;
    int mValue = numbers.get(m);
    if (value == mValue) {
        return true;
    }
    if (value > mValue) {
        List<Integer> rightNumbers = numbers.subList(m + 1, numbers.size());
        return binarySearch(rightNumbers,value);
    }

    if (value < mValue) {
        List<Integer> leftNumbers = numbers.subList(0, m);
        return binarySearch(leftNumbers,value);

    }

    return false;
}

合并两个有序的数组,合并后依然有序

public int[] merge(int[] a,int[] b) {
    int ai = 0;int bi = 0;int j = 0;
    int[] result = new int[a.length + b.length];
    while (ai<a.length && bi<b.length) {
        if (a[ai] < b[bi]) {
            result[j++] = a[ai];
            ai ++;
        }else {
            result[j++] = b[bi];
            bi++;
        }
    }

    while (ai < a.length) {
        result[j++] = a[ai++];
    }

    while (bi < b.length) {
        result[j++] = b[bi++];
    }

    return result;
}

简单选择排序

  • 先假设numbers[0]是最小值,第一趟,从第二个到最后一个元素找出比最小值更小的元素numbers[i],然后交换,则numbers[0]是最小值
  • 然后找出次小值与numbers[1]交换
public void selectSort(int[] numbers){
    for (int j = 0;j<numbers.length;j++) {
        int min = numbers[j];
        int minLocation = j;
        for (int i = j+1; i < numbers.length; i++) {
            if (numbers[i] < min) {
                min = numbers[i];
                minLocation = i;
            }
        }
        // 将之前的最小值与现在的最小值交换位置
        int temp = numbers[j];
        numbers[j] = min;
        numbers[minLocation] = temp;
    }
}

快速排序

public int[] quikSort(int[] numbers,int low,int high) {
    if (low<high) {
        int middle = partition(numbers,low,high);
        quikSort(numbers,low,middle-1);
        quikSort(numbers,middle+1,high);
    }

    return numbers;
}

int partition(int[] numbers,int low, int high){
    int middle = numbers[low];
    while (low < high) {
        // 从high端,寻找一个小于middle的记录
        while (low < high && numbers[high] > middle) {
            --high;
        }
        numbers[low] = numbers[high];
        // 从low端,寻找一个大于middle的记录
        while (low < high && numbers[low] < middle) {
            ++low;
        }
        numbers[high] = numbers[low];
    }
    numbers[low] = middle;
    return low;
}

直接插入排序与希尔排序区别

希尔排序:按步长分组,在组内进行直接插入排序,慢慢缩小步长直至步长为1进行最后一次直接插入排序

冒泡排序

public static int[] bubbleSort(int[] numbers) {
    boolean switched = false;
    int tail = 1;
    do {
        for (int i = 0; i < numbers.length - tail; i++) {
            if (numbers[i] > numbers[i+1]) {
                int temp = numbers[i];
                numbers[i] = numbers[i+1];
                numbers[i+1] = temp;
                switched = true;
            }else {
            	// 若没有任何交换则说明已经排好序,跳出循环
                switched = false;
            }
        }
        // 每一轮循环都会确定最后一个元素的位置,每一轮可以少遍历一个元素
        tail ++;
    }while (switched == true);
    return numbers;
}

给定一组单词,找出这组单词中属于某个给定单词的变位词(变位词指一个单词经过改编字母顺序后得到的另一个单词)

  • 每个单词和其变位词都可有一个相同的算法签名,即按照字母顺序排序得到的字母序列
public class Variant {

    Map<String, List<String>> signMap = new HashMap<>();

    public Variant(final List<String> words) {
        for (String word : words) {
            String sign = getWordSign(word);
            if (signMap.containsKey(sign)) {
                signMap.get(sign).add(word);
            }else {
                List<String> wordList = new ArrayList<>();
                wordList.add(word);
                signMap.put(sign,wordList);
            }
        }
    }

    public List<String> getWords(String s){
        String wordSign = getWordSign(s);
        List<String> result = signMap.get(wordSign);
        return result;
    }
    // 获得单词的签名
    private String getWordSign(String word) {
        byte[] bytes = word.getBytes();
        Arrays.sort(bytes);
        return new String(bytes);
    }
}

递归

递归求和1+2+3+…+n
sum(n){
	if(n>1){
		return n+sum(n-1);
	}else{
		return 1;
	}	
}
递归阶乘n! = n * (n-1) * (n-2) * …* 1(n>0)
f(n){
	if(n>1){
		return n*f(n-1);
	}else{
		return 1
	}
}
河内塔问题:一号杆上的珠子上小下大,借助2号杆把1号杆上的珠子移到三号杆而不改变珠子的上下顺序。(1)每次只能移动一个珠子(2)大珠子不能放在小珠子下面。最少移动多少次
	public static void main(String[] args) {
        int nDisks = 3;
        doTowers(nDisks, 'A', 'B', 'C');
    }
    public static void doTowers(int topN, char from, char inter, char to) {
        if (topN == 1){
            System.out.println("Disk 1 from "
                    + from + " to " + to);
        }else {
            doTowers(topN - 1, from, to, inter);
            System.out.println("Disk "
                    + topN + " from " + from + " to " + to);
            doTowers(topN - 1, inter, from, to);
        }
    }

思想:
先将前n-1个移动到B,
再将最后一个移动到C,
最后将前n-1个移动到C

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值