入门不容易->先从数组说起
数据结构,平时用得最多,接触最多的也是数组,先从数组说起。
数组的概念
什么是数组
一组数据,一秒钟可以申明1000个变量的骚操作。
存储相同的类型,连续的存储空间。
最重要的一点:按下标找元素。
数组是如何实现按下标访问元素的?
我们拿一个长度为5的int 类型数组 int [] arr=new int[5]; 来举例,在下面我画的这个图钟,计算机给数组arr,分配了从2000-2019的连续的内存空间,我们假设首地址是2000。下面就是寻址公式:
arr[i]_address=base_address+i*data_type_size; 因为是int类型,data_type_size大小为4。

这里有一个经常的面试考点:数组和链表的区别,很多同学会答,链表的插入和删除时间复杂度为O(n),数组的查找时间复杂度为o(1)。实际上数组的查找操作时间复杂度不是o(1)。你再好的数组,用二分查找时间复杂度都是o(logn)。正确回答,数组支持随机访问,根据下标的查询时间复杂度为o(1)。
数组的初始化方式
动态初始化:
数组类型[] 数组名 = new 数据类型[数组长度];
静态初始化:
简化格式:
数据类型[] 数组名称 = {值, 值, …};
完整格式(推荐):
数据类型[] 数组名称 = new 数据类型[]{值, 值, …};
数组是引用类型
所以下面代码输出多少?
int[] arr1 = new int[5];
int[] arr2 = new int[] { 1, 2, 3, 4, 5 }; arr1 = arr2;
arr2[2] = 8;
Console.WriteLine(arr1[2]);
数组的优缺点
支持下标索引访问,很多时候,我们的数组下标都是没有语义的,在某些情况可以让他有语义。比如特等奖对应0,奖金1000,1等奖,奖金500类似的,不过语义这个也不是啥场合都适合的,大部分场合都是不适合的。
数组内存连续存储,对CPU的缓存也很友好,性能也会更好。
固定了大小,不支持动态扩容,增加和删除数据比较麻烦。
自己实现一个数组
public class MyArray
{
//实现自己的数组
private int size;
private int defaultCapacity;
private int[] data; public MyArray():this(10)
{ } public MyArray(int defaultCapacity)
{
this.defaultCapacity = defaultCapacity;
this.data = new int[defaultCapacity];
} //添加数据逻辑,并且支持动态扩容
public void add(int ele)
{
if (size > defaultCapacity / 2)
{
//自动扩容
defaultCapacity = defaultCapacity + defaultCapacity / 2;
int[] newData = new int[defaultCapacity];
Array.Copy(this.data, newData,size);
this.data = newData;
}
this.data[size] = ele;
size++; } //打印数组
public void print()
{
for(int i = 0; i < size; i++)
{
Console.WriteLine(data[i]);
}
} //获取元素的中的个数
public int getSize()
{
return this.size;
} //删除元素
public void removeEle(int value) { //删除一个数据
int loc = -1;
for(int i = 0; i < size; i++)
{
if (data[i] == value)
{
loc = i;
break;
}
}
if (loc == -1)
{
throw new ArgumentException("没有找到要删除的元素"); }
for(int i = loc; i < size; i++)
{
data[i] = data[i + 1];
}
data[size-1] = 0; //清空数组
size--; } //删除数据根据索引
public void removeIndex(int index)
{
if (index < 0 || index > this.size)
{
throw new ArgumentException("索引不合法");
}
//删除数据,数据往前移动
for(int i = index; i < this.size; i++)
{
this.data[i] = this.data[i + 1];
}
this.data[size - 1] = 0; //清空数组
size--;
} //获取数组的容量
public int getCapacity(int n)
{
return this.defaultCapacity;
} //返回数组是否为空
public bool isEmpty()
{
return this.size == 0;
} //指定索引位置,添加元素。
public void insert(int index,int e)
{
//1、是否队满
if (size == data.Length)
{
throw new ArgumentException("add failed,Array is full");
}
//2、index是否合法。
if(index<0 || index > this.size)
{
throw new ArgumentException("add failed,Required index>0 and index<=size");
} //把数据向后移动
for(int i = this.size; i > index; i--)
{
this.data[i] = this.data[i-1];
}
this.data[index] = e;
size++;
} //是否包含某个元素
public bool contains(int n)
{
for(int i = 0; i < size; i++)
{
if (data[i] == n)
{
return true;
}
}
return false;
} //修改某个元素
public void set(int index,int ele)
{
if (index < 0 || index >= size)
throw new ArgumentException("Set failed. Index is illegal.");
this.data[index] = ele;
}
}
数组的面试题分享
1、实现一个支持动态扩容的数组
2、实现两个有序数组合并为一个有序数组
3、实现一个五子棋盘
4、无序数组,排序去重
5、数组的奇偶调换
6、数组无序且带有下标,排成有序,并输出下标
入门不容易->先从数组说起的更多相关文章
- 《挑战30天C++入门极限》新手入门:C/C++中数组和指针类型的关系
新手入门:C/C++中数组和指针类型的关系 对于数组和多维数组的内容这里就不再讨论了,前面的教程有过说明,这里主要讲述的数组和指针类型的关系,通过对他们之间关系的了解可以更加深入的掌握数组和指 ...
- Java基础(1)IntelliJ IDEA入门、常用快捷键和数组操作
一. IntelliJ IDEA入门 1 快捷键和技巧 智能补全代码,比如只写首字母按回车: psvm+Enter :public stactic void main(String[] args) s ...
- 后缀数组入门(二)——Height数组与LCP
前言 看这篇博客前,先去了解一下后缀数组的基本操作吧:后缀数组入门(一)--后缀排序. 这篇博客的内容,主要建立于后缀排序的基础之上,进一步研究一个\(Height\)数组以及如何求\(LCP\). ...
- [C语言入门笔记]分支结构与数组
分支结构与数组 什么是分支结构? 分支结构是用户或者程序可以选择下一步执行哪个语句 分支结构有哪些? If If Else If Else If Switch 在初学者的学习过程中第一种和第二种比较普 ...
- PHP基础入门(四)---PHP数组实用基础知识
PHP数组 数组是特殊的变量,它可以同时保存一个以上的值. ***关键词:数组基础.数组遍历.超全局数组.数组功能.数组函数. 下面来和大家分享一下有关PHP的数组基础知识,希望对你PHP的学习有所帮 ...
- Java入门篇(四)——数组
上篇在foreach中有引入一个数组的概念,数组是最为常见的一种数据结构,是相同类型的.用一个标识符封装到一起的基本类型数据序列或对象序列. 数组是具有相同数据类型的一组数据的集合,根据维数不同可以分 ...
- Java入门(六):数组
数组是一种数据结构,用于存储同一类型值的集合,也可以看做是数据类型一致的一组数据. 一.语法和声明数组 1.语法:数据类型[ ] array = new 数据类型[长度]: 注意: 使用长度创建数组的 ...
- ES6_入门(4)_数组的解构赋值
//2017/7/14 //变量的解构赋值(解构:Destructuring) //(1)数组的解构赋值 let [a,b,c]=[1,2,3];//模式匹配,只要等号两边的模式相同,左边的变量就会被 ...
- hdu 1277 AC自动机入门(指针版和数组版)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1277 推荐一篇博客(看思路就可以,实现用的是java): https://www.cnblogs.co ...
- Kotlin入门(4)声明与操作数组
上一篇文章介绍了基本变量类型在Kotlin中的用法,不过这只针对单个变量,如果要求把一组相同类型的变量排列起来,形成一个变量数组,那又该如何声明和操作呢? 在Java中声明数组,跟在C语言中声明是一样 ...
随机推荐
- linux搭建本地和网络yum源
[mirrors.163.com] name=mirrors.163.com baseurl=http://mirrors.163.com/centos/7/os/x86_64/ enabled=1 ...
- Linux 集群 和免秘钥登录的方法。
/* 1.1.什么是集群? 很多台服务器(计算机)做相同的事,就称之为集群 服务器和服务器之间必须要处于联通状态(linux01和linux02可以相互访问并且传输数据) 服务器的配置和常见的计算机没 ...
- mysql 相关练习题
/* 自己查询自己 把一张表看成是两张表. 表的设计. SELECT * FROM depart; SELECT d1. NAME '部门', d2. NAME '分部门' FROM depart d ...
- Markdown学习——Typora入门之常用操作语法及其快捷键
Markdown 学习--Typora入门 Markdown是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档. 由于Markdown的轻 ...
- C# 将OFD转为PDF
OFD格式的文档是一种我国独有的国家标准版式的文档,在不同场景需求中,可以通过格式转换的方法将PDF转为OFD,或者将OFD转为PDF.本次内容,将通过C#程序介绍如何实现由OFD到PDF的转换,并附 ...
- Nginx 根据不同的域名来代理转发内部主机-HTTP和HTTPS
一.需求 由于公司只有一个公网,很多 web 项目都想通过 80 或 443 端口来访问,所以需要 Nginx 充当公司网关. 把唯一的公网 IP 80 端口和 443 端口跟 Nginx 网关主机 ...
- redis中scan和keys的区别
scan和keys的区别 redis的keys命令,通来在用来删除相关的key时使用,但这个命令有一个弊端,在redis拥有数百万及以上的keys的时候,会执行的比较慢,更为致命的是,这个命令会阻塞r ...
- bom-对话框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- DLL链接库
转载请注明来源:https://www.cnblogs.com/hookjc/ 2. 静态链接库 对静态链接库的讲解不是本文的重点,但是在具体讲解 DLL 之前,通过一个静态链接库的例子可以快速地帮助 ...
- Redis源码简要分析
转载请注明来源:https://www.cnblogs.com/hookjc/ 把所有服务端文件列出来,并且标示出其作用:adlist.c //双向链表ae.c //事件驱动ae_epoll.c // ...