Java基础知识 15(StringBuffer类,冒泡排序法,选择排序法,直接插入排序,快速排序算法,希尔排序算法,二分法)

Java基础知识 15

StringBuffer类

具体程序运行:E:\Java project\20200501-StringBuffer-练习

如果我们要进行拼串的操作,推荐使用StringBuffer.
StringBuffer长度可变的字符序列。
String长度不可变的字符序列。
StringBuffer()构造一个其中不带字符的字符串缓冲区,初始容量是16个字符,如果字符串长度超过16,则在16的基础上累加。
StringBuffer其实可以看做一个字符容器,不断地往容器中添加数据。我们可以指定初始容量的字符串缓冲区。
获取容量:int capacity = sb.capacity();
往字符串缓冲区添加内容:StringBuffer sb2=sb.append(“a”);如果超过了默认的容量,会自动扩充
获取容器长度:int length=sb.length();
(这里我们用一杯水举例,水杯的容量是500ml,实际上装水100ml,这里的500ml实际上就是获取容量,100ml实际上就是获取容器长度)
(1)append()往容器中追加数据,可以把任意类型追加到数据中。

public class Mytest2 {
    public static void main(String[] args) {
        //往容器中追加内容,返回的还是缓冲区对象本身。
        StringBuffer sb = new StringBuffer();
        StringBuffer sb2 = sb.append("123");
        System.out.println(sb==sb2);
        System.out.println("------------------");
        //链式编程,往容器中添加数据。
        StringBuffer sb3 = sb.append("123").append("abc").append("456").append("def");
        System.out.println(sb3==sb);
        System.out.println("------------------");
        //取出容器中的内容,容器中的内容会以字符串的形式出现
        //StringBuffer重写了toString()方法,以字符串的形式返回
        String s = sb.toString();
        System.out.println(s);
    }
}

(2)insert()方法,可以在指定的位置上插入任意数据,返回的还是字符串缓冲区对象本身。
(3)deleteCharAt()方法,根据索引删除容器中的一个字符,返回的还是容器本身。
(4)delete()方法,可以删除一段字符(含头不含尾)
(5)replace()方法,根据起始索引和终止索引,替换一段内容,返回的还是容器本身。
(6)reverse()方法,反转容器中的数据。
(7)substring()方法,根据起始索引和终止索引,截取一段内容,以String类型返回,不会影响原容器。
(8)int indexOf(String str),从头查找该字符串,在容器中第一次出现的索引。
int indexOf(String str,int fromIndex),从指定位置查找该字符串第一次出现的位置。
int lastIndexOf(String str);
int lastIndexOf(String str,int fromIndex);

public class Mytest4 {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("1111");
        sb.append("2222");//往容器中追加数据
        //insert()方法,可以在指定位置插入任意数据,返回的还是字符串缓冲区本身
        StringBuffer sb2 = sb.insert(4, "3333");
        System.out.println(sb2);
        StringBuffer sb3 = sb.insert(0, "0000");
        System.out.println(sb3);
        System.out.println("------------------");
        //deleteCharAt()方法,根据索引删除容器中的一个字符,返回的还是容器本身
        StringBuffer sb4 = sb.deleteCharAt(0);
        System.out.println(sb4);
        System.out.println("------------------");
        StringBuffer sb5 = sb.deleteCharAt(0);
        System.out.println(sb5);
        System.out.println("------------------");
        //delete()方法,可以删除一段字符,含头不含尾
        StringBuffer sb6 = sb.delete(2, 4);
        System.out.println(sb6);
        System.out.println("------------------");
        //replace()方法,根据起始索引和终止索引,替换一段内容,也是含头不含尾,返回的还是容器本身
        StringBuffer sb7 = sb.replace(10, 12, "44");
        System.out.println(sb7);
        System.out.println("------------------");
        //reverse()方法,返回容器中的数据
        StringBuffer sb8 = sb.reverse();
        System.out.println(sb8);
        System.out.println("------------------");
        //subString()方法,根据起始索引和终止索引,截取一段内容,以String类返回,不会影响原容器
        String sb9 = sb.substring(4, 6);
        System.out.println(sb9);
        System.out.println("------------------");
        //indexOf(String str),从头查找该字符串第一次出现的索引
        int i = sb8.indexOf("11");
        System.out.println(i);
        System.out.println("------------------");
        //indexOf(String str,int fromIndex)方法,从指定位置查找该字符串第一次出现的位置
        int j = sb8.indexOf("00", 3);
        System.out.println(j);
        //lastIndexOf(String str)反向索引(不举例了,同上思考一下即可)
        //lastIndexOf(String str,int fromIndex)反向索引(不举例了,同上思考一下即可)
        System.out.println("------------------");
    }
}

String类型和StringBuffer类型的相互转换

public class Mytest {
    public static void main(String[] args) {
        //StringBuffer类型和String类型相互转换
        //StringBuffer----->String转换
        StringBuffer s1 = new StringBuffer("aaa");
        s1.append("bbb").append("ccc").append("ddd");
        //1.用toString()方法**记住**
        String s2 = s1.toString();
        System.out.println(s2);
        System.out.println("-----------------");
        //2.用subString()方法
        String s3 = s1.substring(0);
        System.out.println(s3);
        System.out.println("-----------------");
        //3.用String类中的构造方法
        String s4 = new String(s1);
        System.out.println(s4);
        System.out.println("-----------------");
        //String------->StringBuffer转换
        //1.采用StringBuffer的构造方法
        StringBuffer s5 = new StringBuffer(s1);
        System.out.println(s5);
        //2.使用append(),insert()方法
        StringBuffer s6 = new StringBuffer();
        s6.append("123");
        s6.insert(0,222);
        System.out.println(s6);
    }
}

StringBuffer和StringBuilder的区别:
他们两个的API是相同的。
区别:线程安全方面的区别:
1.StringBuffer是线程安全的,效率低。
2.StringBuilder是线程不安全的,效率高,多线程环境下,可能会存在线程安全问题。

StringBuilder 一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,
但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,
用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,
建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

数组排序

详细程序运行:E:\Java project\20200501-数组排序-练习

把一个无序序列,通过比较交换等手段,使其变为一个有序数列。

冒泡排序法(必须手写记住)

数组中的元素两两比较,大的往后放,经过一轮比较后,最大的元素就出现在最后面。

import java.util.Arrays;

public class Mytest {
    public static void main(String[] args) {
        //数组排序:把一个无序序列,通过比较交换等手段,使其变成一个有序序列。
        //数组排序:冒泡排序,选择排序,插入排序,快速排序,归并排序,基数排序,堆排序,等

        //冒泡排序:数组中的元素两两比较,大的往后放,经过一轮比较后,最大的元素,就出现在了最后面。
        //冒泡排序法
        int[] arr={26,14,35,16,50};
        //外层循环控制轮次
        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]){
                    //进行值交换
                    int t=arr[j];
                    arr[j]=arr[j+1];
                    arr[j +1]=t;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
        System.out.println("------------------------");
        //第一次轮回
        for (int j = 0; j < arr.length-1; j++) {
            if(arr[j]>arr[j+1]){
                //进行值交换
                int t=arr[j];
                arr[j]=arr[j+1];
                arr[j +1]=t;
            }
        }
        //第二次轮回
        for (int j = 0; j < arr.length-1-1; j++) {
            if(arr[j]>arr[j+1]){
                //进行值交换
                int t=arr[j];
                arr[j]=arr[j+1];
                arr[j +1]=t;
            }
        }
        //第三次轮回
        for (int j = 0; j < arr.length-1-2; j++) {
            if(arr[j]>arr[j+1]){
                //进行值交换
                int t=arr[j];
                arr[j]=arr[j+1];
                arr[j +1]=t;
            }
        }
        //第四次轮回
        for (int j = 0; j < arr.length-1-3; j++) {
            if (arr[j] > arr[j + 1]) {
                //进行值交换
                int t = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = t;
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}
选择排序法(必须手写记住)

从0索引处的元素开始,依次跟它后面的元素挨个比较,小的往前放,经过比较,最小的就出现在最前面。

import java.util.Arrays;

public class Mytest2 {
    public static void main(String[] args) {
        //选择排序法
        int[] arr={87,65,54,35,21};
        //外层循环控制轮数
        for (int index = 0; index < arr.length - 1; index++) {
            //内层循环控制次数
            for (int i = 1+index; i < arr.length; i++) {
                if(arr[index]>arr[i]){
                    int t=arr[i];
                    arr[i]=arr[index];
                    arr[index]=t;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

        System.out.println("-----------------------");
        //第一轮
        int index=0;
        for (int i = 1; i < arr.length; i++) {
            if(arr[index]>arr[i]){
                int t=arr[i];
                arr[i]=arr[index];
                arr[index]=t;
            }
        }
        System.out.println(Arrays.toString(arr));
        //第二轮
        index=1;
        for (int i = 1+index; i < arr.length; i++) {
            if(arr[index]>arr[i]){
                int t=arr[i];
                arr[i]=arr[index];
                arr[index]=t;
            }
        }
        System.out.println(Arrays.toString(arr));
        //第三轮
        index=2;
        for (int i = 1+index; i < arr.length; i++) {
            if(arr[index]>arr[i]){
                int t=arr[i];
                arr[i]=arr[index];
                arr[index]=t;
            }
        }
        System.out.println(Arrays.toString(arr));
        //第四轮
        index=3;
        for (int i = 1+index; i < arr.length; i++) {
            if(arr[index]>arr[i]){
                int t=arr[i];
                arr[i]=arr[index];
                arr[index]=t;
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}
直接插入排序(必须手写记住)

每次那后面的一个元素,插入到之前的一个有序序列中,使之仍然保持有序。

import java.util.Arrays;

public class Mytest3 {
    public static void main(String[] args) {
        int[] arr={87,65,54,35,21};
        //直接插入排序
        //外层循环控制轮数
        for (int i = 1; i < arr.length; i++) {
            //内层循环控制次数
            for(int j=i;j>0;j--){
                if(arr[j]<arr[j-1]){
                    int t=arr[j];
                    arr[j]=arr[j-1];
                    arr[j-1]=t;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}
快速排序算法(必须手写记住)

分治法:比大小,再分区。
1.从数组中取一个数,作为基准数。
2.分区:将比这个数大或者等于的数全部放在他的右边,小于它的数全部放在左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
实现思路:
1.将基准数挖出后形成第一个坑。
2.由前向后查找比它小的数,挖到后挖出此数填到前一个坑中。
3.由前向后查找比他大或者等于的数,找到后也挖出填到前一个坑中。
4.再重复执行2.3操作。

import java.util.Arrays;

public class Mytest {
    public static void main(String[] args) {
        //快速排序法
        int[] arr={20, 30, 2, 3, 5, 6, 8, 1, 0, 10, -1, 20, 100, 50, 30, 9, 8};
        ArraysUtils.quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
}
-----------------------------------------
public class ArraysUtils {
    //快速排序算法
    /**
     *
     * @param arr
     * @param start
     * @param end
     */
    public static void quickSort(int[] arr,int start,int end){
        if(start<end){
            //递归
            //获取基准数的中间索引值,左右两区的界限
            int index= getIndex(arr, start, end);
            //对左区进行递归
            quickSort(arr,start,index-1);
            //对右区进行递归
            quickSort(arr,index+1,end);
        }
    }
        /*挖坑填数
            1. 将基准数挖出形成第一个坑。
            2.由后向前找比他小的数,找到后挖出此数填到前一个坑中。
            3.由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
            4.再重复执行2,3两步骤。*/
    public static int getIndex(int[] arr, int start, int end) {
        int i=start;
        int j=end;
        //找一个数作为基准数
        int x=arr[i];
        // 4.再重复执行2,3两步骤。
        while(i<j){
            //2.由后向前找比他小的数,找到后挖出此数填到前一个坑中。
            while(i<j&&arr[j]>=x){
                j--;
            }
            //找到之后,挖坑填数
            if(i<j){
                arr[i]=arr[j];
                i++;//下次从前往后找,填完坑后,让递增
            }
            //3.下一次由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
            while(i<j&&arr[i]<x){
                i++;
            }
            //找到之后,挖坑填数
            if(i<j){
                arr[j]=arr[i];
                j--;//下次从后往前找,填完坑后,让递减
            }
        }
        //让基准数填到最后一个坑中
        arr[i]=x;
        return i;//最后i和j重合,i=j,返回基准数所在的位置
    }
}
希尔排序

希尔排序原理:是对插入排序的一种优化,核心思想是合理选取增量,经过一轮排序之后,会让序列大致有序。然后不断缩小增量,进行插入排序,直到增量为1,整个排序结束。
直接插入排序,其实是增量为1 的希尔排序。

public class MyTest {
    public static void main(String[] args) {
        int[] arr={46,55,13,42,17,94,5,70,9,5,6,89,50,50,255};
        shellSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    private static void shellSort(int[] arr) {
       for(int h=arr.length/2;h>0;h/=2){
            for(int i=h;i<arr.length;i++){
                for(int j=i;j>h-1;j-=h){
                    if(arr[j]<arr[j-1]){
                        int temp=arr[j];
                        arr[j]=arr[j-1];
                        arr[j-1]=temp;
                    }
                }
            }
        }
        //克努特序列
        //int h=1;
        //h=h*3+1;
        //根据克努特序列选取第一次的增量
       /* int jiange=1;
        while(jiange<=arr.length/3){
            jiange=jiange*3+1;
        }
        for(int h=jiange;h>0;h/=2){
            for(int i=h;i<arr.length;i++){
                for(int j=i;j>h-1;j-=h){
                    if(arr[j]<arr[j-1]){
                        int temp=arr[j];
                        arr[j]=arr[j-1];
                        arr[j-1]=temp;
                    }
                }
            }
        }*/
    }
}
二分法查找元素出现的索引

前提是数组有序,思路如下:

public class Mytest2 {
    public static void main(String[] args) {
        //二分法,前提是数组有序
        int[] arr = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
        int index= getIndex(arr,60);
        System.out.println("索引是:"+index);
    }
    public static int getIndex(int[] arr,int element) {
        //定义最小索引
        int minIndex=0;
        //定义最大索引
        int maxIndex=arr.length-1;
        //定义中间索引
        int centerIndex=(minIndex+maxIndex)/2;
        while(minIndex<maxIndex){
            if(arr[centerIndex]==element){
                return centerIndex;
            }else if(element>arr[centerIndex]){
                minIndex=centerIndex+1;
            }else if(element<arr[centerIndex]){
                maxIndex=centerIndex-1;
            }
            //z再一次计算中间索引
            centerIndex=(maxIndex+minIndex)/2;
        }
        return -1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值