一数据结构与算法入门
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。算法+数据结构=程序。程序的好坏=时间复杂度+空间复杂度+应用场景。
1.时间复杂度:关键代码执行的次数,比如下面这段代码
public void function1(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
//do someting
}
}
for(int i=0;i<n;i++){
//do something
}
//do something 时间复杂度是1
}
时间复杂度就是指 do something,do something就是我们说的关键代码。
两个for循环的时间复杂度是o(n)=n^2; 一个for循环的时间复杂度是o(n)=n;所以上面function1的时间复杂度是o(n)=n^2+n+1
我们再看下function2
public void function2() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// do someting
}
}
}
很明显它的时间复杂的是o(n)=n^2;
假设这两个方法都解决了问题,那么funtion1和funtion2的算法哪一个更优呢?你可定回答funtion2;恭喜你答错了。其实这两个算法没有孰优孰劣之分,它们的时间复杂度是相等的。我们假设n趋近于无穷大的时候,数据量无限多的时候,这两种情况其实是相等的,我们看时间复杂度主要是看n的几次方。
2;空间复杂度;
我们来看下数值交换的代码;
int a = 5;
int b = 6;
int t = a;
a = b;
b = t;
空间复杂度就是三个变量。我们现在让空间少一个。
int a=15;
int b=9;
a=a^b;
b=a^b;
a=a^b;
二进制的抑或运算:1表示真,0表示假。符号不相同的时候(一个为1,一个为0),结果就是真1,符号相同的时候(两个同为0,或者同为1),结果就为假0。
如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
3,顺序表;
线性表,包括顺序存储结构,比如ArrayList和链式存储结构。顺序存储结构的表就叫顺序表。
我们要研究顺序表的增删改查
(1)查询
public int search(int[] array,int a){
for(int i=0;i<array.length;i++){
//查询a是否在array里,是的话返回它的位置,否就返回-1
if(array[i]==a){
return i;
}
}
return -1;
}
(2) 改:也很简单直接修改值就行了。这里就不写代码了。
(3)插入:
// 在第index个地址插入数据a
public void insert(int[] array, int index,int a) {
for (int i = array.length - 1; i > index; i--) {
array[i] = array[i - 1];
}
array[index]=a;
}
(4)删除
// 在第index个地址删除数据
public static void delete(int[] array, int index) {
for (int i = index; i <array.length-1; i++) {
array[i] =array[i+1] ;
}
}
4冒泡排序
看下代码
第一轮排序的写法
public static void main(String[] args) {
int[] a = new int[] { 1, 9, 6, 4, 8 };
bubbleSort(a);
for(int i=0;i<a.length;i++){
System.out.print(a[i]+",");
//输出1,6,4,8,9,
}
}
// 第一轮排序
public static void bubbleSort(int[] array) {
for (int j = 0; j < array.length - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
可以看到9,已经在最后面了。我们下面在执行循环的时候就可以去掉9了,因为9已经排好序了,只排前面的数据就可以了。第二次排序for循环就是n-1,第三次for循环就是n-2,依次类推。一直到1;
代码就是这样的
// j<i中的i就是我们每一轮都要-1
public static void bubbleSort(int[] array) {
for (int i = array.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
我们看下时间复杂度,第一次for循环,是n次,第二次for循环是n-1;依次类推。一直到最后1。所以时间复杂度是
n(n-1)/2。
我们在来优化下
public static void bubbleSort(int[] array) {
for (int i = array.length - 1; i > 0; i--) {
boolean flag = true;
for (int j = 0; j < i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
flag = false;
}
}
if (flag) {
break;
}
}
}
5,选择排序:
public static void main(String[] args) {
int[] a = new int[] { 3, 1, 5, 8, 2, 9, 4, 6,7 };
selectSort(a);
}
public static void selectSort(int[] array) {
int index = 0;
for (int j = 1; j < array.length; j++) {
if (array[j] < array[index]) {
index = j;
}
}
System.out.print(index);//输出是4,正好是1的位置
}
上面的代码我们发现index已经指向了最小的数据。下面我们把两个值进行交换。
public static void selectSort(int[] array) {
int index = 0;
for (int j = 1; j < array.length; j++) {
if (array[j] < array[index]) {
index = j;
}
}
int temp = array[index];
array[index] = array[0];
array[0] = temp;
}
这一轮排序的结果是1,3,5,8,2,9,4,6,7,
代码就是这样的。
public static void selectSort(int[] array){
for(int i=0;i<array.length-1;i++) {
int index = i;
for (int j = i+1; j < array.length; j++) {
if (array[j] < array[index]) {
index = j;
}
}
//{1,2,5,8,3,9,4,6,7};
if(index!=i) {//如果已经是最小的,就不需要交换
int temp = array[index];
array[index] = array[i];
array[i] = temp;
}
}
}