数据结构

数据结构

对数组或链表进行一系列操作,结合面向对象和方法的基本知识对数据到数组在到对象的封装;来代创建一些复杂的对象来代表特殊的数据或对象。

一.动态数组

1.创建一个动态的数组;可以添加删除插入和遍历。

封装一个数组对象,在一个class文件内,没有main入口。在另外一个Test.class文件中通过创建数组对象来调用这个class文件中的变量和方法来对数组进行操作。(功能的封装必须在class非主方法外才能通过对象来调用)。
	package 数据结构;

public class Test {
	int [] arr= new int[5];
	int index=0 ;
	public void add(int n) {
		
		if(index==arr.length) {
			
			int temp[]=new int [arr.length+10];
			/*for(int i=0;i<arr.length;i++) {
				temp[i]=arr[i];
			}*/
			
			System.arraycopy(arr, 0, temp, 0, arr.length);
			
			arr =temp;
		}
		arr[index++]=n;
		
		
	
	
	}
	//非强制便利
	public void show() {
		for(int i=0;i<index;i++) {
			System.out.print(arr[i]+" ");
		} }    
//插入
public void insert(int index_,int k) {
	if(index_>index&&index_<0) {
		System.out.println("输入不合法");
		
	}else {
		 if(index_==arr.length) {
			 int temp[]=new int[arr.length+10];//创建新数组
			 for(int i=0;i<arr.length;i++) {//将老数组中的值转移到新数组
				 temp[i]=arr[i];//
			 }
			 arr=temp;//将新数组的地址转换到老地址arr; 
		 }//注意要更改新数组的范围,在移位之前
			 //移位
			 
			 for(int i=index-1;i>=index_;i--) {
				 arr[i+1]=arr[i];
				 
			 }
			 arr[index_]=k;
			 index++;
		 
		
	}
	
}
	//update
	public void update(int index_,int a) {
		if(index_>=index&&index_<0) {
			System.out.println("输入有误");
			
		}else {
			arr[index_]=a;
		}
	}
	//删除
	public void dlete(int index_) {
		if(index_>index&&index_<0) {
			System.out.println("输入有误");
		}else {
			for(int i= index_;i<index;i++) {
				arr[i]=arr[i+1];
			}
			index--;
		}
		
	}
}
测试程序 Test2.class文件
package 数据结构;

public class Test2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Test a=new Test();//通过创建数组对象,数组对象的封装源码必须写在class成员变量内;否则调用不出来
		a.add(1);
		a.add(2);
		a.add(2);
		a.add(2);
		a.add(2);
		a.add(2);
		a.add(2);
		a.add(2);
		a.add(2);
		a.add(2);
		a.add(5);
		a.add(5);
		a.add(5);
		a.add(5);
		a.add(5);
		a.add(5);
		a.add(5);
		a.insert(3, 100);
		a.show();
			
		
		
		
		
	}

}
   

2.数组的扩容

package 数组.扩容;

import java.util.Arrays;

;



public class Default {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		 m1();
	}

	private static void m1() {
		//调用System.arrayCopy()实现数组元素的复制。Ctrl{

		int []data= {23,54,67,78,34,89};
		
		//定义更大的数组
		int [] newData=new int[data.length*2];
		//把原来的内容赋值到新数组
		//System.arraycopy(初始数组,起始位,新数组,起始位,多少个);
		System.arraycopy(data,0, newData, 0, data.length);//JNI技术,在Java中调用其他语言代码
		//这个方法没有方法体;及 System.arraycopy();
			
		
		//让原来的数组名指向新的数组
		data= newData;
		System.out.println(Arrays.toString(data));
	}

}

3.数组的删除

package 数组.删除;

import java.util.Arrays;

//定义一个方法,删除指定元素
public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
	public void delete(int data [],int i){
		//1.定义较小的数组
		int [] newDate=new int [data.length-1];
		//2.把0,1复制到新的数组中,在i+1开始到 data.length
		for(int t=0;t<i ;t++) {
			newDate[t]=data[t];
			
		}
		for(int t=i+1;t<data.length;t++) {
			newDate[t-1]=data[t];
		}
		//4.让原来的数组指向新的数组
		data= newDate;
		//打印data
		System.out.println(Arrays.toString(data));
		
	}

}

二.动态链表

1.创建一个单项链表,可以插 删 改查等动态操作。与动态数组相比,插删改效率更高。在链表中没有下标的概念


## 创建一个节点类

```c
package 数据结构;



public class Node {
	int value;
	Node next;//Node类型,代表下一个节点的是next,
	//可以通过next.value 和next.next来表示这个节点的值和下一个节点的名称
	

	

	}

封装链表

package 数据结构;





public class MyLinked {
	Node n1;//存的一个 链表的头 Node是自己创建的类
	int size=0;//链表元素的个数
	public void add(int a) {
		if(size==0) {
			Node node=new Node();
			node.value=a;
			node.next=null;
			n1 =node;//n1是第一个节点
			size++;
			
		}else {
			Node node=new Node();
			node.value=a;
			node.next=null;//创建最后这个节点为node
			Node tail=n1;//认为要插入的节点上一个节点定为tail,并默认时n1;并且遍历直到找到node.tail
			while (tail.next!=null) {
				tail=tail.next;
			}
			tail.next=node;//将要加入的新节点node(是通过新定义的类Node创建的)插入到tail后面
		}
		
	}
	//链表的遍历
	public void foreach() {
		Node tail=n1;
		while(tail.next!=null) {//当链表内下个值不为null,说明是中间元素。
			System.out.println(tail.value+" ");
			tail=tail.next;//在循环内说明tail不是最后的元素,将下一个节点传给tail直到跳出循环
		}//跳出循环后,输出的tail就是最后的元素,tail.next=null.遍历已经全部遍历
	}
	//链表插入不需要考虑移位
	public void insert(int v,int a) {//v是链表中要插入值之前的那个值
		node tail=n1;//设置为n1,表示从n1的位置开始遍历,直到不满足循环的条件
		while(tail.value!=v) {//循环遍历直到找到v这个结果的节点
			tail=tail.next;
			
		}
		//创建这个要插入的节点
		Node node=new Node();
		node.value=a;
		node.next=tail.next;
		tail.next=node;//把新创建的节点添加到tail后,
		size++;
		
		
		

	}
	public void delete(int v) {
		Node tail=n1;
		while(tail.next.value!=v) {//判断当前节点下一个节点是否被删除,跳出循环被删要
			tail=tail.next;
		}
		tail.next=tail.next.next;//被删除的节点直接被在下一个节点取代掉
		size--;
		
		
		
	}
	public void update(int v,int v1) {
		Node tail=n1;
		while(tail.value!=v) {//判断当前节点下一个节点是否被删除,跳出循环被删要
			tail=tail.next;
		}
		tail.value=v1;//被删除的节点直接被在下一个节点取代掉
	
		
		
		
	}
	public int size() {
		return size;
	}
	


}

## 测试类

```c


```java
```c
package 数据结构;

public class lion {
	public static void main(String[] args) {
		MyLinked a =new MyLinked();
		a.add(5);
		a.add(6);
		a.add(1);
		a.add(6);
		a.add(7);
		a.add(3);
		a.add(9);
		a.add(6);
		a.add(7);
		a.foreach();
		
	}
	
}



三.队列

1.队列常用于解决高并发、优先级等问题;需要自己设置相应的算法来解决。 实现了动态队列

 package 队列;
public class Default {

		
		int[] arr  =new int[10];
		int size=0;
	
		//追加元素 入队列
		public void push(int a) {//常规操作,和栈差不多
			if(size==arr.length) {
				int[] temp=new int[arr.length+arr.length>>1];
				System.arraycopy(arr, 0, temp, 0, arr.length);
				arr=temp;
			}
			arr[size++]=a;//size要先赋值,在增一。表示的是刚加入的元素
		}
		
		//出队列,删除
		public int pop() {//需要向前移位
			int temp=arr[0];//移位后头头元素会发生变化,故先赋值给temp
			for(int i= 0;i<size;i++) {
				arr[i]=arr[i+1];//移位
			}
			size--;
			return temp;
		}
		//查看头元素
		public int peek(){
			return arr[0];
		}		
		//循环
		public void foreach() {
			for(int i=0;i<size;i++) {
				System.out.println(arr[i]+" ");
			}

		}
		//获取大小
		public int size() {
			return size;
		}
	

}
//高并发问题 同一时刻很多人访问服务器
/*1.用队列
 * 
 * 2.负载均衡
 * 		
 * 
 * 
 * 
 * */
//发邮件

2.插入排序法实现优先级

按大小来排队列,大的数靠前排;默认大的优先级高
package 队列.优先级;
//插入排序法,越大越靠前
//或者哈希算法来
public class Default {
	int[] arr  =new int[10];
	int size=0;

	//追加元素 入队列
	public void push(int a) {//常规操作,和栈差不多
		if(size==arr.length) {
			int[] temp=new int[arr.length+arr.length>>1];
			System.arraycopy(arr, 0, temp, 0, arr.length);
			arr=temp;
		}
		//将a插入合适的位置,用插入排序9631 5该擦到6后面
		int index =0;//认为在第0个位置是合适的
		boolean flag=false;
		for(int i=0;i<size;i++) {//可能全部走完一圈也没
			if(a>arr[i]) {
				index=i;
				flag=true;//表面未遍历完就找到了位置
				break;
			}
		}
		if(flag) {//表明进去了if语句
			//移位
			for(int k=size-1;k>=index;k--){//向后移,从后往前循环
				arr[k+1]=arr[k];
			
			}
			arr[index]=a;
			size++;
		}else {
			index=size;
			arr[index]=a;
			size++;
		}
		
		
	}
	
	//出队列,删除
	public int pop() {//需要向前移位
		int temp=arr[0];//移位后头头元素会发生变化,故先赋值给temp
		for(int i= 0;i<size;i++) {
			arr[i]=arr[i+1];//移位
		}
		size--;
		return temp;
	}
	//查看头元素
	public int peek(){
		return arr[0];
	}		
	//循环
	public void foreach() {
		for(int i=0;i<size;i++) {
			System.out.println(arr[i]+" ");
		}

	}
	//获取大小
	public int size() {
		return size;
	}

}
测试类Test
	package 队列.优先级;

public class Test {

	public static void main(String[] args) {
		Default a=new Default();
		a.push(5);
		a.push(1);
		a.push(9);
		a.push(8);
		a.push(6);
		a.push(4);
		a.push(3);
		a.push(7);
		a.foreach();
	
		

	}

}

3.循环队列

package 队列.循环;
//一个圈,首尾相连。不考虑优先级
/*加入是放在队尾,只有查看大小不用该
 * 
 * */
public class Default {
	int[] arr  =new int[10];
	int size=0;
	/*int first=0;//代表有一个元素
	int tail=0;*/
	int first_index=-1;
	int tail_index=-1;

	//追加元素 入队列
	public void push(int a) {//常规操作,和栈差不多
		//为空,插入一个首尾都
		if(first_index==-1&&tail_index==-1) {
			arr[++tail_index]=a;//
			first_index++;
			
		}else {
			arr[++tail_index]=a;//if else里都有++tail_index;可以拿出来去掉else在if后表示
		}
		size++;
		
	}
	
	//出队列
	public int pop() {//需要向前移位
		//就一个元素,取完后尾和头都变-1
		//多个元素,只改头指向下个
		int temp;
		if(size==1) {
			temp=arr[first_index];
			first_index=-1;
			tail_index=-1;
		}else {
			temp=arr[first_index];//将头元素指向下一个元素
			if(first_index==arr.length) {
				first_index=0;//归零,因为循环是一个圈0,1,2,3,4,5,6,7,8,9
			}
		}
		size--;
		return temp;//查看抛出的元素
	}
	//查看头元素
	public int peek(){
		return arr[first_index];//直接指向头文件指向的位置
	}		
	//循环  改功能未实现
	/*public void foreach() {
		for(int i=0;i<size;i++) {
			int index=first_index;
			System.out.println(index);
			if(first_index==tail_index) {
				System.out.println(index++);
				break;
			}else {
				System.out.println(index++);
				if(first_index==)
			}
		}

	}*/
	//获取大小
	public int size() {
		return size;
	}


}

1.搜索树
节点左右孩子所存储的值呈现左<根<右;称搜索树 可以直接去掉一半的值进行比较,效率高
2.平衡树
高度差<=1称平衡树
改为平衡树: 单旋和双旋(单旋:提起较深一段的父类 双选:提起父类和跟类中间;提起的那段的尾端放在最左面的下面)
3.树的代码实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值