数据结构+算法=程序
结构:实体+关系
数据结构的三个方面:逻辑结构(线性(表,栈,队列,串)树,图,二叉树,线性表),存储结构(顺序方法,链接方法,索引方法,散列方法),运算
索引方法(是顺序存储的延伸)和散列方法(借助顺序存储的按照下标来存储的o1的思想,不仅是存储方法,也是运算方法)使数据的检索更加高效
内存:算法运行速度快
外存:相比内存的读取数据,比内存满二十五万倍
一刀切上式:事先补齐法
public class A {
public static void main(String[] args) {
//上式:事先补齐
String s="abc ttt,kmd,uuu xyz";
String s2="";
s+=',';//一刀切
for (int i = 0; i < s.length(); i++) {
char c=s.charAt(i);
if(c==' ' || c==','){
System.out.println(s2);
s2="";
}
else
s2+=c;
}
}
}
冒泡排序:
整体思路就是把最大的数依次往后挪
思路:相邻两个数据进行比较,如果位置不对,进行交换,整个数组中未排序的数都比较了一遍。(这样比较完一次使得最大的数在最后边)
每一趟保证把最大的数挪到当前未排好序的数据的最后。(要比较n-1趟)
每一趟要比较多少次(第一趟:n-1次。后面会随着趟数的增加,比较次数会逐渐减少,每次减少1)
用外层循环控制趟数,用内层循环控制次数。
代码实现:
public class BubbleSort {
public static void main(String[] args) {
int[] number = { 18, 32, 26, 11, 9, 13, 24, 35, 24 };
int n = number.length;
for (int i = 1; i < n - 1; i++) {// n-1趟
for (int j = 1; j < n - i; j++) {// 每趟里面比较多少次
if (number[j - 1] > number[j]) {// 将大的数向后挪
int temp = number[j - 1];
number[j - 1] = number[j];
number[j] = temp;
}
}
}
// 打印
for (int i = 0; i < number.length; i++) {
System.out.print(number[i] + "\t");
}
}
}
快速排序:在元素数据很大的时候效率十分明显。
思想:先去找一个元素作为标尺,我们通常选第一个元素
将这个标尺的元素设为x。然后把比x大 的放在右边,把比x小的放在左边
代码实现思路:要想进行递归完成快速排序就需要先进行一趟排序,将标尺元素放在数组的中间,得出标尺左边是比标尺小的数据,标尺右边是比标尺大的元素。然后对标尺左边和标尺右边的元素进行递归排序。
原来的数据
取标尺
第一个位置的5原来在倒数第二的位置上,将5和标尺进行
两边都有一个指针,左边的向右移动,右边的向左移动。直到左右指针撞到一起就完成了排序。
用代码递归的完成排序(一):
package cn.taiji.com.com;
public class MyA {
static void show(int[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + "");
System.out.print(" ");
}
}
static void quickSort(int[] a, int begin, int end) {
if (end - begin <= 1) {// 不需要排序
return;
}
int x = a[begin];// 用begin元素(第一个元素)作为标尺
int p1 = begin;// 定义两个指针,一个从开始位置指向
int p2 = end;// 一个从结束位置指向
boolean dr = true;// 比较条件
// 当p1等于p2的时候,排序结束
// 正向,标尺拿走之后,p1位置的是空位,我们需要从p2位置逐步的向左来比较,发现更小的元素
L1: while (p1 < p2) {
if (dr) {
for (int i = p2; i > p1; i--) {
if (a[i] <= x) {
a[p1++] = a[i];
p2 = i;
dr = !dr;// 表示原来向左比较,现在向右,原来如果向右,现在向左比较。
continue L1;
}
}
// 不满足条件的元素怎样处理
p2 = p1;
}
// 向左比较
else {
for (int i = p1; i < p2; i++) {
if (a[i] >= x) {
a[p2--] = a[i];
p1 = i;
dr = !dr;
continue L1;
}
}
p1 = p2;// 将左指针移动到右指针位置
}
}
// 最后将标尺元素塞入到指针相撞的位置
a[p1] = x;
quickSort(a, begin, p1 - 1);
quickSort(a, p1 + 1, end);
}
public static void main(String[] args) {
int[] a = { 15, 22, 13, 9, 16, 33, 15, 23, 18, 4, 33, 25, 14 };
show(a);
quickSort(a, 0, a.length - 1);// 快速排序需要递归来完成,除了传递数据,还需要传递数据的范围
System.out.println();
show(a);
}
}
用代码递归的完成排序(二):
package cn.taiji.com.com;
public class QuickSort {
public static void quickSort(int[] arr, int start, int end) {
if (start < end) {
// 拆分索引位
int index = getIndex(arr, start, end);
//向左递归
quickSort(arr, 0, index - 1);
//向右递归
quickSort(arr, index + 1, end);
}
}
/**
* 分区并返回索引值
*
* @param arr
* @param start
* @param end
* @return
*/
public static int getIndex(int[] arr, int start, int end) {
int i = start;
int j = end;
// 第一个坑位
int x = arr[i];// x是基准数
while (i < j) {
// 先从右向左对比,比小于x的
while (i < j && arr[j] >= x) {
j--;
}
if (i < j) {
// 把找到的元素放在第一个坑位
arr[i] = arr[j];
i++;
}
// 从左边向右对比,大于等于x的数
while (i < j && arr[i] < x) {
i++;
}
if (i < j) {
arr[j] = arr[i];
j--;
}
}
arr[i] = x;
return i;
}
public static void main(String[] args) {
int[] arr = { 5, 3, 9, 1, 6, 7, 2, 4, 0, 8 };
quickSort(arr, 0, arr.length - 1);
for (int i : arr) {
System.out.print(i+" ");
}
}
}
那么我们可以思考如果这个给的数据有的顺序已经排好,有的趟不需要交换。那么还要交换就影响效率。
解决办法:
public class BubbleSort {
public static void main(String[] args) {
int[] number = { 18, 32, 26, 11, 9, 13, 24, 35, 24 };
int n = number.length;
for (int i = 1; i < n - 1; i++) {// n-1趟
boolean flag=false;
for (int j = 1; j < n - i; j++) {// 每趟里面比较多少次
if (number[j - 1] > number[j]) {// 将大的数向后挪
int temp = number[j - 1];
number[j - 1] = number[j];
number[j] = temp;
flag=true;
}
}
if(!flag){//说明没有进上面的for循环,没有交换
break;
}
}
// 打印
for (int i = 0; i < number.length; i++) {
System.out.print(number[i] + "\t");
}
}
}
由于还是调换次数很多,所以冒泡排序的效率还是很低。
选择排序:不稳定的,但是效率高
public class Choose {
public static void main(String[] args) {
int[] nums = { 34, 4, 56, 17, 90, 65 };
int minIndex = 0;// 用于记录每次比较的最小值下标
// 控制轮数
for (int i = 0; i < nums.length - 1; i++) {
minIndex = i;// 每轮假设一个最小值下标
for (int j = i + 1; j < nums.length; j++) {
if (nums[minIndex] > nums[j]) {
minIndex = j;
}
}
// 判断需要交换的数下标是否为自己
if (minIndex != i) {
nums[minIndex] = nums[minIndex] + nums[i];
nums[i] = nums[minIndex] - nums[i];
nums[minIndex] = nums[minIndex] - nums[i];
}
}
// 输出结果
for (int n : nums) {
System.out.print(n + " ");
}
}
}
插入排序:从后向前找到合适的位置后插入
基本思想:每步
我们取第一个数作为基准,找这个数的下一个数(4)。i为下标,从0开始。
第一轮:i=1,temp=4;拿4和34比,那么我们要把4插入到34前面,那么需要34向后挪,最后4是从temp中取出。
第二轮:i=2,temp=56;结果:4,34,56,17,90,65;由于34本身就比56小,所以不需要向前插入。注意向前比较的时候如果比较一次满足,那么久不需要再向前继续比较。
第三路:i=3;temp=17;17和56比;4,34,56,56,90,65;4,34,34,56,90,65;最后将17放在第二个位置,结果为4,17,34,56,90,65
第四轮:i=4;temp=90;不需要挪,因为90比56大。
第五轮:i=5;temp=65;65和90比,90向后挪,65和56比大,不需要挪了。所以最后90向后挪,把temp里的65放在原来90的位置;结果4,17,34,56,65,90
代码:
public class InsertSort {
public static void main(String[] args) {
int[] nums = { 34, 4, 56, 17, 90, 65 };
// 控制比较的轮数
for (int i = 1; i < nums.length; i++) {// i从1开始表示从第二个元素向前插入
int temp = nums[i];// 记录操作数
int j = 0;
for (j = i - 1; j >= 0; j--) {// j=i-1表示当前这个元素的前一个元素的下标,最多比较到第0的元素
if (nums[j] > temp) {
nums[j + 1] = nums[j];// 将4的位置赋值为34
} else {
break;
}
}
if (nums[j + 1] != temp) {// 把0的位置赋值为4
nums[j + 1] = temp;
}
}
// 输出结果
for (int n : nums) {
System.out.print(n + " ");
}
}
}
归并排序:是很有意义的经典算法
就是把两个已经排序好的队列合成为一个有序队列。就是将两个有序队列合并为一个有序队列。
关键是怎样将两个有序队列归并为一个有序队列:
1.我们需要一个新的数组来存放排序好的队列,这个队列的大小为两个归并队列的和。
2.需要两个指针,分别指向两个队列的第一个元素。
3.将两个指针所指的位置的元素进行比较,将较小的放在新数组的第一个位置。然后移动相应的指针。
4.一个队列元素耗尽,则另一个队列剩余元素都拷贝到新队列尾部。
代码实现:
/**
* 归并排序:将两个有序数组合为一个有序数组
*
* @author Alisa
*
*/
public class SSort {
public static void main(String[] args) {
int[] a = { 5, 8, 11, 19, 22, 25 };
int[] b = { 7, 9, 20, 30, 35, 38, 40 };
int[] c = merge(a, b);
for (int i = 0; i < c.length; i++) {
System.out.print(c[i] + " ");
}
}
private static int[] merge(int[] a, int[] b) {
//
int[] x = new int[a.length + b.length];
int ai = 0;
int bi = 0;
int xi = 0;// 记录当前已经放到了第几个元素
// 添加一个循环,表示任何一方耗尽就停止
while (ai < a.length && bi < b.length) {
if (a[ai] <= b[bi]) {
x[xi++] = a[ai++];
} else {
x[xi++] = b[bi++];
}
}
// 此时表示至少有一方数组结束
while (ai < a.length) {
x[xi++] = a[ai++];
}
while (bi < b.length) {
x[xi++] = b[bi++];
}
return x;
}
}