向程序员靠近:自我学习记录-数据结构(1)

(注:用于自我学习,记录自学数据结构的笔记,可能会有错误,如果看到发现啦可以提醒我一下,谢谢!)

一、数组

1、如何在Java中定义数组?

  • 静态定义(指定数据内容但是不指定长度):
    int[] array = new int[] {0,1,2,3,4,5,6,7,8,9};

  • 动态定义(指定长度但是不指定内容):
    int[] array = new int[10];
    数组的长度和内容只能够指定其中一个,不能即指定长度又指定内容,也不能不指定长度,也不指定内容

2、数组的内存特性
定长且连续,定长导致增删慢,连续导致遍历快。

快速随机访问公式:数组目标元素内存地址 = 数组的首元素地址 + (数组元素占用内存大小 * 目标元素下标)

3、数组典型例题

数组逆序排列:给定一个数组{1,2,3,4,5}逆序输出为{5,4,3,2,1}

public void reverse(int[]array){
	int i = 0;
	int j =array.length-1;
while(i<j){
	int tmp = array[i];
	array[i] = array[j];
	array[j] = tmp;
	
	i++;
	j--;
	}

}

二、链表

1、链表基本概念
链表的构成:节点—data数据域+next后继指针域。

链表的链表的第一个节点(头结点)通常不存储任何数据,最后一个节点的后继指针域取值为null。

2、链表的内存特性
不定长且不连续,不定长导致增删快,不连续导致遍历慢。

  • ArrayList:底层是数组,定长且连续,定长导致增删慢,连续导致遍历快。
  • LinkedList:底层是链表,不定长且不连续,不定长导致增删快,不连续导致遍历慢。

三、栈和队列

栈结构

1、栈:元素先进后出。
最先加入的元素称为栈底元素,反之最后进入栈结构的元素为栈顶元素。

2、Java中的栈结构:Stack
Stack类是List接口的实现类,同样属于Collection接口的实现类之一,能够有序可重复的保存元素。

3、通过栈结构实现数组逆序

public void reverse(int[] array){
	Stack<Integer> s = new Stack<>();//new一个栈对象,把数组所有元素放入栈
	for(int i : array){
		s.push();//通过遍历将数组中所有元素入栈
	}
	int k = 0;//出栈元素在数组中的下标
	while(!s.isEmpty()){
		array[k++] = s.pop();//元素出栈,存储在array中
	}
}

队列结构

1、队列:元素先进先出。
元素出队列的一端称为队头(front),入队列的一端称为队尾(rear)。

2、Java中的队列结构:LinkedList
Stack类是List接口的实现类,同样属于Collection接口的实现类之一,能够有序可重复的保存元素。

基本排序算法

基本概念

1、算法的时间复杂度和空间复杂度
算法问题的规模,实际上就是这个算法解决的问题中,保存数据多少的一种描述。
时间复杂度:一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),存在一个正常数c使得fn*c>=T(n)恒成立。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。

  • 忽略公式中的常数项
  • 忽略公式的低次幂项,仅保留公式中的最高次幂项
  • 忽略公式中最高次幂项的系数
  • 如果一个公式中所有的项都是常数项,那么这个算法的时间复杂度统一表示成O(1)。

在排序算法中,常见的时间复杂度及大小关系:O(n^2)>O(nlogn)>O(n)
时间复杂度最大,算法运行效率最低,最慢。

空间复杂度:空间复杂度是指算法在计算机内执行时所需存储空间的度量。记作:S(n)=O(f(n))
算法执行期间所需要的存储空间包括3个部分:
算法程序所占的空间;
输入的初始数据所占的存储空间;
算法执行过程中所需要的额外空间。

在排序算法中,常见的空间复杂度及大小关系:O(n)>O(logn)>O(1)

2、排序算法的稳定性及复杂度
(1)稳定的排序算法
(2)不稳定的排序算法
在这里插入图片描述

最基本的排序:冒泡排序

**1、排序原理:**相邻位比较,反序则互换
2、代码实现(从内向外写)

public void bubbleSort(int[] array){
//3、创建一个循环,控制比较的轮次 0开始
for(int i = 0;i<=array.length-2;i++){
	for(int j = 0;j+1<=array.length-1-i;j++){//2、创建循环,控制相邻位比较的次数
		if(array[j]>array[j+1]){//1、相邻位比较,反序则互换
			int tmp = array[j];
			array[j] = array[j+1];
			array[j+1] = tmp;
		}
	}
}
}

选择排序

**1、排序原理:**选定一个标准位,将待排序序列中的元素与标准位元素逐一比较,反序则互换。
2、代码实现

public void selectSort(int[] array){

//3、创建一个循环,控制标准位下标i的移动
for(int i = 0;i<=array.lenth-2;i++){
//2、创建一个循环,控制待排序序列的下标j,控制向前走
	for(int j = array.lenth-1;j >i;j--){
		//1、标准位和待排序序列中的元素进行比较
		if(array[i] > array[j]){
			int tmp = array[i];
			array[i] = array[j];
			array[j] = tmp;
			}
		}
	}
}

插值排序

**1、排序原理:**将待排序序列中的第一个元素,与前面有序序列中的元素逐一比较,反序则互换并继续向前比较。
2、代码实现

public void insertSort(int[] array){
	for(int i = 1;i<array.length;i++){
		for(int j = i;j-1>=0&&array[j]<array[j-1];j--){
		int tmp = array[j];
		array[j] = array[j-1];
		array[j-1] = tmp;
		}
	}
}

希尔排序

**1、希尔排序:**希尔排序的实际上是一种变形的插值排序。它将整个序列按照规定的步长(step)进行分部分取值,并将这些值进行插值排序,是排序算法中第一个时间复杂度突破O(n^2)的排序算法。【缩小增量法】步长取值为长度的一半

希尔排序是在一轮排序之后,将步长折半,以此类推,当步长取值为1的时候,整个希尔排序就成为了一个单纯的插值排序。
2、代码实现

public void shellSort(int[] array){
	//1、创建一个循环,维护步长的变化
	int step = array.length/2;
	while(step>=1){//使用这个循环控制步长的变化,>=1就可以继续进行
	//创建一个循环,控制在当前步长范围内,数组所有元素参与比较
	for(int start = 0;start<step;start++){//在一轮比较内,使用这个循环的 控制变量表示插值排序元素起点的下标
	//在议一轮排序内部,相隔step的多个元素之间进行了场插值排序
	insertSort(array,start,step);
		}
		step/=2;
	}
}
//希尔排序内使用插值排序
public void insertSort(int[] array,int start,int step){
	for(int i = start+step;i<array.length;i+=step){
		for(int j = i;j-step>=0 && array[j]<array[j-step];j-=step){
		int tmp = array[j];
		array[j] = array[j-step];
		array[j-step] = tmp;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值