数据结构与算法基础
概述
数据结构概述
数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成
数据的存储结构
把数据元素存放在地址连续的存储单元里、其数据间的逻辑关系和物理关系是一致的、数组就是顺序存储结构的典型代表
把数据元素存放在内存中的任意存储单元里、也就是可以把数据存放在内存的各个位置、这些数据在内存中的地址可以是连续的、也可以是不连续的
数据的逻辑结构
集合结构中的数据元素同属于一个集合、他们之间是并列的关系、除此之外没有其他关系
线性结构中的元素存在一对一的相互关系
树形结构中的元素存在一对多的相互关系
图形结构中的元素存在多对多的相互关系
算法概述
是指解题方案的准确而完整的描述、是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制
算法的特性
算法的基本要求
线性结构
数组
数组的基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class AddData {
public static void main(String[] args) {
int [] arr = new int[] {5,2,1};
System.out.println(Arrays.toString(arr));
int number = 0;
int [] newArr = new int[arr.length + 1];
newArr[arr.length] = number;
for(int i = 0; i < arr.length; i++){ newArr[i] = arr[i]; }
arr = newArr;
System.out.println(Arrays.toString(arr)); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class DeleteData {
public static void main(String[] args) {
int [] arr = new int[]{9,8,7,6,5,4,2,1,4,5,6,7};
System.out.println(Arrays.toString(arr)); int [] newArr = new int[arr.length - 1];
int number = (int) (Math.random() * 10);
System.out.println(number);
for(int i = 0; i < number; i++){ newArr[i] = arr[i]; } for(int i = number+1; i < arr.length; i++){ newArr[i - 1] = arr[i]; }
arr = newArr;
System.out.println(Arrays.toString(arr)); } }
|
查找算法
线性查找就是从数组头部开始、依次向后查找、一直到查到结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class Wire {
public static void main(String[] args) {
int[] elements = new int[]{1,6,5,43,1,56,4,1,4,1,54,2,43};
int index = -1;
int target = 5;
for(int i = 0; i < elements.length; i++ ){ if(elements[i] == target){ index = i; break; } } System.out.println("index = " + index); } }
|
首先二分法查找的数组必须为有序的、然后取数组中间位置查看、查看此刻的值与要查询的值的关系、如果相对较小则取较小的一边、然后再次取中间位置查看、再次进行比较、依此类推此法、相对较大则同理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class Dichotomy {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5,6,7,8,9};
int index = -1;
int target = 5;
int begin = 0;
int end = arr.length - 1;
int mid = (begin + end) / 2;
while (true){ if(arr[mid] == target){ index = mid; break; }else{ if(target < arr[mid]){ end = mid - 1; }else{ begin = mid + 1; } mid = (begin + end) / 2; } } System.out.println("index = " + index); } }
|
面向对象的数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| public class MyArrays {
private int[] elements;
public MyArrays(){ this.elements = new int[0]; }
public void add(int element){ int[] newArr = new int[elements.length + 1];
for(int i = 0; i <elements.length; i++){ newArr[i] = elements[i]; } newArr[elements.length] = element;
this.elements = newArr; }
public void add(int index,int element){
int[] newArr = new int[elements.length + 1];
for (int i = 0; i < elements.length; i++){ if(i < index){ newArr[i] = elements[i]; } else{ newArr[i+1] = elements[i]; } } newArr[index] = element;
this.elements = newArr; }
public void delete(int index){
int[] newArr = new int[elements.length - 1];
for(int i = 0; i < newArr.length; i++){ if(i < index){ newArr[i] = elements[i]; }else{ newArr[i] = elements[i+1]; } } this.elements = newArr; }
public void update(int index, int element){
if(index < 0 || index > elements.length - 1){ throw new RuntimeException("数组下标越界"); }
this.elements[index] = element; }
public int get(int index){
if(index < 0 || index > elements.length - 1){ throw new RuntimeException("数组下标越界"); } return elements[index]; }
public int size(){
return elements.length; }
public void show(){ System.out.println(Arrays.toString(this.elements)); }
public int wire(int target){
for(int i = 0; i < elements.length; i++ ){ if(elements[i] == target){ return i; } } return -1; }
public int dichotomy(int target){
int begin = 0;
int end = elements.length - 1;
int mid = (begin + end) / 2;
while (true){
if(begin >= end){ return -1; }
if(elements[mid] == target){ return mid; }else{ if(target < elements[mid]){ end = mid - 1; }else{ begin = mid + 1; } mid = (begin + end) / 2; } } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public class Test {
public static void main(String[] args) { MyArrays arrays = new MyArrays();
arrays.add(1); arrays.add(2); arrays.add(3); arrays.add(4); arrays.add(5); arrays.add(6); arrays.add(7); arrays.add(8); arrays.add(9);
System.out.println(arrays.wire(4)); System.out.println(arrays.dichotomy(0));
arrays.add(2,5); arrays.show(); System.out.println("----------------");
arrays.delete(1); arrays.show(); System.out.println("----------------");
System.out.println("数组的长度为:" + arrays.size()); System.out.println("----------------");
System.out.println(arrays.get(2)); System.out.println("----------------");
arrays.update(2,100); arrays.show(); } }
|
栈
栈的数据特点是顺序结构、先进后出
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| public class MyStack {
private int[] elements;
public MyStack(){ this.elements = new int[0]; }
public void push(int element){ int[] newArr = new int[elements.length + 1];
for(int i = 0; i <elements.length; i++){ newArr[i] = elements[i]; } newArr[elements.length] = element;
this.elements = newArr; }
public int pop(){
if(elements.length == 0){ throw new RuntimeException("栈是空的"); }
int element = this.elements[elements.length - 1];
int[] newArr = new int[elements.length - 1];
for(int i = 0; i < elements.length - 1; i++){ newArr[i] = this.elements[i]; }
this.elements = newArr;
return element; }
public int peek(){ if(elements.length == 0){ throw new RuntimeException("栈是空的"); } return this.elements[elements.length - 1]; }
public String isEmpty(){
return this.elements.length == 0?"栈是空的":"栈不是空的"; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class testStack {
public static void main(String[] args) { MyStack myStack = new MyStack();
myStack.push(9); myStack.push(8); myStack.push(7); myStack.push(6);
System.out.println(myStack.isEmpty()); System.out.println(myStack.pop()); System.out.println(myStack.pop()); System.out.println(myStack.pop()); System.out.println(myStack.pop()); System.out.println(myStack.isEmpty()); System.out.println(myStack.peek()); } }
|
队列
队列的数据特点是顺序结构、先进先出
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| public class MyQueue {
private int[] elements;
public MyQueue(){ this.elements = new int[0]; }
public void add(int element){ int[] newArr = new int[elements.length + 1];
for(int i = 0; i <elements.length; i++){ newArr[i] = elements[i]; } newArr[elements.length] = element;
this.elements = newArr; }
public int poll(){
int element = this.elements[0];
int[] newArr = new int[elements.length - 1];
for(int i = 0; i < newArr.length; i++){ newArr[i] = elements[i +1]; }
this.elements = newArr;
return element; }
public String isEmpty(){
return this.elements.length == 0?"队列为空":"队列不为空"; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class TestQueue {
public static void main(String[] args) { MyQueue mq = new MyQueue();
mq.add(5); mq.add(2); mq.add(0);
System.out.println(mq.isEmpty());
System.out.println(mq.poll());
mq.add(6);
System.out.println(mq.poll()); mq.add(7); System.out.println(mq.poll()); mq.add(8); System.out.println(mq.poll()); System.out.println(mq.poll()); System.out.println(mq.poll()); System.out.println(mq.isEmpty()); } }
|
单链表
单链表的数据结构是链表的形式存储的、当存储数据的同时要存储下一个结点的地址
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| public class MyNode {
private int data;
private MyNode next;
public MyNode(int data){ this.data = data; }
public MyNode append(MyNode node){
MyNode currentNode = this;
while(true){
MyNode nextNode = currentNode.next;
if(null == nextNode){ break; } currentNode = nextNode; } currentNode.next = node;
return this; }
public int getData(){ return this.data; }
public MyNode next(){ return this.next; }
public String islast(){ return this.next == null?"下一个结点为空":"下一节点不为空"; }
public void deleteNode(){
MyNode newNode = this.next.next;
this.next = newNode; }
public void insert(MyNode node){
MyNode nextNext = this.next;
this.next = node;
node.next = nextNext; }
public void show(){
MyNode currentNode = this;
while(true){ System.out.print(currentNode.data + " ");
currentNode = currentNode.next;
if(currentNode == null){ break; } } System.out.println(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class TestNode {
public static void main(String[] args) {
MyNode node1 = new MyNode(1); MyNode node2 = new MyNode(2); MyNode node3 = new MyNode(3); MyNode node4 = new MyNode(4);
node1.append(node2).append(node3).append(node4);
node1.show();
node1.next().insert(new MyNode(9));
node1.show(); } }
|
循环链表
循环链表就是最后一位的下一节点是起始位
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| public class LoopNode {
private int data;
private LoopNode next = this;
public LoopNode(int data){ this.data = data; }
public int getData(){ return this.data; }
public LoopNode next(){ return this.next; }
public void deleteNode(){
LoopNode newNode = this.next.next;
this.next = newNode; }
public void insert(LoopNode node){
LoopNode nextNext = this.next;
this.next = node;
node.next = nextNext; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void main(String[] args) { LoopNode loopNode1 = new LoopNode(1); LoopNode loopNode2 = new LoopNode(2); LoopNode loopNode3 = new LoopNode(3); LoopNode loopNode4 = new LoopNode(4);
loopNode1.insert(loopNode2); loopNode2.insert(loopNode3); loopNode3.insert(loopNode4); System.out.println(loopNode1.next().getData()); System.out.println(loopNode2.next().getData()); System.out.println(loopNode3.next().getData()); System.out.println(loopNode4.next().getData()); }
|
双链表
双链表的数据结构是存储两个节点、一个存储上一个节点、一个存储下一个节点、因为双链表是循环的所以没有最后一个节点
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public class DoubleNode {
private DoubleNode pre = this;
private DoubleNode next = this;
private int data;
public DoubleNode(int data){ this.data = data; }
public DoubleNode getPre(){ return this.pre; }
public DoubleNode getNext(){ return this.next; }
public int getData(){ return this.data; }
public void inser(DoubleNode node){
DoubleNode nextNext = this.next;
this.next = node;
node.pre = this;
node.next = nextNext;
nextNext.pre = node;
} }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class TestDoubleNode {
public static void main(String[] args) {
DoubleNode node1 = new DoubleNode(1); DoubleNode node2 = new DoubleNode(2); DoubleNode node3 = new DoubleNode(3);
node1.inser(node2); node2.inser(node3);
System.out.println(node2.getPre().getData()); System.out.println(node2.getData()); System.out.println(node2.getNext().getData()); } }
|
递归
在一个方法(函数)的内部调用该方法(函数)本身、并且有一个条件能使它停止调用自己本身 的编程方式
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class TestRecursion {
public static void main(String[] args) {
printf(10); }
public static void printf(int i){
if(i >0){ System.out.println(i); printf(i - 1); } } }
|
斐波那契数列
第一位为1、第二位为1、其余后面的都为 前两位相加的和
1、1、2、3、5、8 ……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class FBNQ {
public static void main(String[] args) {
int i = 10; while (i > 0){ System.out.println(printf(i)); i--; } }
public static int printf(int i){ if((i == 1) || (i == 2)){ return 1; }else{ return printf(i - 2) + printf(i - 1); } } }
|
正确的开始、微小的长进、然后持续、嘿、我是小博、带你一起看我目之所及的世界……