一、查找
1. 冒泡排序
原理:比较两个相邻的元素,将值大的元素交换至右端。
用时间复杂度来说:
1.如果我们的数据正序,只需要走一趟即可完成排序。所需的比较次数C和记录移动次数M均达到最小值,即:Cmin=n-1;Mmin=0;所以,冒泡排序最好的时间复杂度为O(n)。
2.如果很不幸我们的数据是反序的,则需要进行n-1趟排序。每趟排序要进行n-i次比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:
冒泡排序的最坏时间复杂度为:O(n2) 。
综上所述:冒泡排序总的平均时间复杂度为:O(n2) 。
代码实现:
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. 选择排序
原理:简单选择排序是最简单直观的一种算法,每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。
- 从待排序列中选出最小(或最大)的一个元素,记录其下标(数组)的位置;
- 将记录的下标值与待排序列的第一个元素进行交换;
- 以此类推,直到全部待排序列的元素排完。
选择排序是不稳定的排序方法。
时间复杂度: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. 插入排序
- 从数组第一个元素开始(0下标),该元素可以认为已经被排序;
- 取出待排序列中第一个元素,然后从“有序”序列中,从后往前扫描;
- 如果该元素(有序序列)大于待插入元素(待排序列),将该元素后移一个位置;
- 重复步骤3,直到找到“有序序列”中某一元素小于或等于“待插入元素”的位置;
- 将待插入元素插入到该元素(有序序列)后面(i+1)的位置上;
- 重复步骤2~5,直到待排序列中没有元素。
直接插入排序的时间复杂度为 o(n^2)。
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);
}
}