目录
什么是数据结构?
简单地说,数据结构是以某种特定的布局方式存储数据的容器。这种“布局方式”决定了数据结构对于某些操作是高效的,而对于其他操作则是低效的。首先我们需要理解各种数据结构,才能在处理实际问题时选取最合适的数据结构。
为什么我们需要数据结构?
数据是计算机科学当中最关键的实体,而数据结构则可以将数据以某种组织形式存储,因此,数据结构的价值不言而喻。无论你以何种方式解决何种问题,你都需要处理数据——无论是涉及员工薪水、股票价格、购物清单,还是只是简单的电话簿问题。数据需要根据不同的场景,按照特定的格式进行存储。有很多数据结构能够满足以不同格式存储数据的需求。
1.数组
数组是最简单、也是使用最广泛的数据结构。栈、队列等其他数据结构均由数组演变而来。下图是一个包含元素(1,2,3和4)的简单数组,数组长度为4。
每个数据元素都关联一个正数值,我们称之为索引,它表明数组中每个元素所在的位置。大部分语言将初始索引定义为零。
数组分为两种类型:一维数组,多维数组;
1.1数组基本操作
1)Insert——在指定索引位置插入一个元素
2)Get——返回指定索引位置的元素
3)Delete——删除指定索引位置的元素
4)Size——得到数组所有元素的数量
1.2数组常见面试算法
1.2.1寻找数组中第二小的元素
public void secondMax(int[] arrays){
if(arrays.length == 0) return;
int max = arrays[0];
int secondMax = arrays[0];
for(int i=1; i<arrays.length; i++){
if(max<arrays[i]){
secondMax = max;
max = arrays[i];
}
}
System.out.println(secondMax);
}
1.2.2找到数组中第一个不重复出现的整数
public void firstNoRepeat(int[] arrays){
//双循环
//遍历所有元素
for(int i=0; i<arrays.length; i++){
int count = 1;
//与比较arrays[i]元素比较是否相等
for(int l=0; l<arrays.length; l++){
if(arrays[i] == arrays[l] && i!=l){
count++;
break;//重复元素退出当前循环
}
}
if(count == 1){//第一次出现不重复的元素
System.out.println(arrays[i]);
break;
}
}
//借助HashMap存储元素,值做为key
HashMap<Integer, Integer> map = new HashMap<>();
for(int i=0; i<arrays.length; i++){
if(map.get(arrays[i]) == null){
map.put(arrays[i], 1);
}else {
int value = map.get(arrays[i]);
map.put(arrays[i], value+1);
}
}
//判断第一次出现一次的整数
for(int i=0; i<arrays.length; i++){
if(map.get(arrays[i]) == 1){
map.get(arrays[i]);
break;
}
}
}
1.2.3合并两个有序数组
int[] sortone = new int[]{1,30,30,100,101,345,346};
int[] sorttwo = new int[]{1,2,30,300,301,302,400,405,406};
mergeSort(sortone, sorttwo);
public void mergeSort(int[] sortone, int[] sorttwo){
int one = 0;
int two = 0;
int[] merge = new int[sortone.length+sorttwo.length];
int index = 0;
while (one<sortone.length && two<sorttwo.length){
if(sortone[one]<=sorttwo[two]){
merge[index++] = sortone[one++];
}else {
merge[index++] = sorttwo[two++];
}
}
while (one<sortone.length){
merge[index++] = sortone[one++];
}
while (two<sorttwo.length){
merge[index++] = sorttwo[two++];
}
System.out.println(merge);
}
1.2.4重新排列数组中的正值和负值
将数组里的负数排在数组的前面,正数排在数组的后面。但不改变原先负数和正数的排列顺序;
int v[] = {-5, 2, -3, 4, -8, -9, 1, 3, -10};
//int v[] = {-5, 2, -3, 4, -8, -9, 1, 3, 12, 15, 19, -7,-2,};
//int v[] = {-1, -3, -5, -7, 1, 3, 5, 7, 9};
public void process(int[] negative){
int[] negativecopy = new int[negative.length];
int begin = 0;
int end = negative.length-1;
for(int l=begin, r=end; l<negative.length&&r>=0;l++, r--){
if(negative[l]<0){
negativecopy[begin++] = negative[l];
}
if(negative[r]>=0){
negativecopy[end--] = negative[r];
}
}
System.out.println(negativecopy);
}
2.栈(后进先出)
著名的撤销操作几乎遍布任意一个应用。但你有没有思考过它是如何工作的呢?这个问题的解决思路是按照将最后的状态排列在先的顺序,在内存中存储历史工作状态(当然,它会受限于一定的数量)。这没办法用数组实现。但有了栈,这就变得非常方便了。
可以把栈想象成一列垂直堆放的书。为了拿到中间的书,你需要移除放置在这上面的所有书。这就是LIFO(后进先出)的工作原理。
下图是包含三个数据元素(1,2和3)的栈