数据结构:计算机存储、组织数据的方式。
数据结构下又分:
1.集合结构:数据结构中的元素之间除了"同属一个集合" 的相互关系外,别无其他关系;
2.线性结构:数据结构中的元素存在一对一的相互关系;
3.树形结构:数据结构中的元素存在一对多的相互关系;
4.图形结构:数据结构中的元素存在多对多的相互关系。
常用的线性结构有:线性表,栈,队列,双队列,数组,串。
常见的非线性结构有:二维数组,多维数组,广义表,树(二叉树等),图。
一颗树可以简单的表示为根, 左子树, 右子树。 左子树和右子树又有自己的子树。
结点的度(Degree of Node):结点所拥有的一级
树的度(Degree of Tree):树中各结点度的最大值。子树的个数
叶子结点(Leaf Node):度为0的结点,也叫终端结点
树的深度(Depth of Tree):树中结点的最大层次数
无序树(Unordered Tree):树中任意一个结点的各孩子结点之间的次序构成无关紧要的树。通常树指无序树
有序树(Ordered Tree):树中任意一个结点的各孩子结点有严格排列次序的树。二叉树是有序树
图形结构中任意两个数据元素间均可相关联,每个结点的前驱结点数和后续结点数可以任意多个。
数组的缺点呢,就是大小固定,查找百万级别的大数据慢。
//number=array.length
public void insert(int value){
array[number] = value;
number++;
}
public int find(int value){ //其时间为O(n)
for (int i= 0; i < number; i++) {
if(array[i]==value)
return i;
}
return number;
}
<pre name="code" class="html"> public int find(int value){ //<span style="font-family: Arial, Helvetica, sans-serif;">但二分查找算法则更优,因为其查找时间为O(lgn)</span>
int start = 0;
int end = number-1;
while(end>=start){
int index =(end + start)/2;
if(array[index]==value){
return index;
}else if(array[index] >value){
end = index-1;
}else {
start = index+1;
}
}
return number;
}
public static void main(String[] args) {
int a[] = {1,2,3,4,4,4,3,1,2,3 };
int c[] = new int[5];//c是用来存放每个数字出现次数的数组
for (int i = 0; i < c.length; i++) {
for (int j = 0; j < a.length; j++) {
if(i == a[j])
c[i]++;
}
}
System.out.println(Arrays.toString(c));
//[0, 2, 2, 3, 3] 原来写错了,【0,2,2,3,2】 4有3次
for (int i = 1; i < c.length; i++) {
c[i] = c[i] +c[i-1];
}
System.out.println(Arrays.toString(c));
//[0, 2, 4, 7, 10] ,这里相对的也写错了。
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[c[a[i]]-1] = a[i];
c[a[i]]--;
}
System.out.println(Arrays.toString(b));
}
栈
public class Stack {
private int array[];
private int max;
private int top;
public Stack(int max){
this.max = max;
array = new int[max];
top = 0;
}
public void push(int value){
if(isFull()){
System.out.println("full,can not insert");
return;
}
array[top++]=value;
}
public int pop(){
return array[--top];
}
public boolean isEmpty(){
if(top == 0){
return true;
}
return false;
}
public boolean isFull(){
if(top == max ){
return true;
}
return false;
}
public void display(){
while(!isEmpty()){
System.out.println(pop());
}
}
public static void main(String[] args) {
Stack s = new Stack(5);
s.push(1);
s.push(3);
s.push(5);
s.push(5);
s.push(5);
s.display();
}
}
队列
public class Queqe {
private int array[];
private int front;
private int end;
private int number;
private int max;
private Queqe(int maxsize){
array = new int[maxsize];
max = maxsize;
front = 0;
end = 0;
number = 0;
}
private void insert(int item){
if(isFull()){
System.out.println("is full,can not insert");
return;
}
array[end++] = item;
number++;
}
private int remove(){
if(isEmpty()){
System.out.println("is empty,can not remove");
return -1;
}
number--;
return array[front++];
}
private boolean isFull(){
return number == max;
}
private boolean isEmpty(){
return number == 0;
}
private int size(){
return number;
}
private int peekFront(){
return array[front];
}
public static void main(String[] args) {
Queqe q = new Queqe(4);
System.out.println("queqe is empty:"+q.isEmpty());
q.insert(1);
q.insert(2);
q.insert(3);
q.insert(4);
q.insert(5);
System.out.println(q.size());
System.out.println("front is "+q.peekFront());
while(!q.isEmpty())
System.out.println(q.remove());
}
}
result:
queqe is empty:true
is full,can not insert
4
front is 1
1
2
3
4
树
public class BinTreeTraverse2 {
private int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
private static List<Node> nodeList = null;
/**
* 内部类:节点
*
* @author ocaicai@yeah.net @date: 2011-5-17
*
*/
private static class Node {
Node leftChild;
Node rightChild;
int data;
Node(int newData) {
leftChild = null;
rightChild = null;
data = newData;
}
}
public void createBinTree() {
nodeList = new LinkedList<Node>();
// 将一个数组的值依次转换为Node节点
for (int nodeIndex = 0; nodeIndex < array.length; nodeIndex++) {
nodeList.add(new Node(array[nodeIndex]));
}
// 对前lastParentIndex-1个父节点按照父节点与孩子节点的数字关系建立二叉树
for (int parentIndex = 0; parentIndex < array.length / 2 - 1; parentIndex++) {
// 左孩子
nodeList.get(parentIndex).leftChild = nodeList
.get(parentIndex * 2 + 1);
// 右孩子
nodeList.get(parentIndex).rightChild = nodeList
.get(parentIndex * 2 + 2);
}
// 最后一个父节点:因为最后一个父节点可能没有右孩子,所以单独拿出来处理
int lastParentIndex = array.length / 2 - 1;
// 左孩子
nodeList.get(lastParentIndex).leftChild = nodeList
.get(lastParentIndex * 2 + 1);
// 右孩子,如果数组的长度为奇数才建立右孩子
if (array.length % 2 == 1) {
nodeList.get(lastParentIndex).rightChild = nodeList
.get(lastParentIndex * 2 + 2);
}
}
/**
* 先序遍历
*
* 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
*
* @param node
* 遍历的节点
*/
public static void preOrderTraverse(Node node) {
if (node == null)
return;
System.out.print(node.data + " ");
preOrderTraverse(node.leftChild);
preOrderTraverse(node.rightChild);
}
/**
* 中序遍历
*
* 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
*
* @param node
* 遍历的节点
*/
public static void inOrderTraverse(Node node) {
if (node == null)
return;
inOrderTraverse(node.leftChild);
System.out.print(node.data + " ");
inOrderTraverse(node.rightChild);
}
/**
* 后序遍历
*
* 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
*
* @param node
* 遍历的节点
*/
public static void postOrderTraverse(Node node) {
if (node == null)
return;
postOrderTraverse(node.leftChild);
postOrderTraverse(node.rightChild);
System.out.print(node.data + " ");
}
public static void main(String[] args) {
BinTreeTraverse2 binTree = new BinTreeTraverse2();
binTree.createBinTree();
// nodeList中第0个索引处的值即为根节点
Node root = nodeList.get(0);
System.out.println("先序遍历:");
preOrderTraverse(root);
System.out.println();
System.out.println("中序遍历:");
inOrderTraverse(root);
System.out.println();
System.out.println("后序遍历:");
postOrderTraverse(root);
}
}
输出结果:
Java代码 收藏代码
先序遍历:
1 2 4 8 9 5 3 6 7
中序遍历:
8 4 9 2 5 1 6 3 7
后序遍历:
8 9 4 5 2 6 7 3 1