数据结构之数组链表树小结

最近学习了数据结构中的数组、链表和树,写得过程并没有出现什么很难解决的困难,但是总需要对自己的思路进行一次又一次的整理,并且在这个过程找的自己的错误以及对编码思路进行优化。在这里分享的主要是自己写得代码。

数组的性质:数组是定长的(在数组声明时,一定要写明数组的大小,否则会报错)
,有序的,数组中的每个元素都有一个唯一的索引位置。
数组的定义:类型[] 变量的名称=new 类型[大小]
e.g.
int[] arr=new int[]{1,2,3};
String[] arr2=new String[]{“a”, “abc”};
数组的实现:
这里只将数组类的定义写出来:

//输出的数组中的位置从一开始,但是储存的数组中位置从零开始。
例如12,23,34这个数组中,输出时显示的是1:12,2:23,3:34,但是在计算机中储存的时候,是0:12,1:23,2:34.

public class ArrayList implements List{
    private Object[] oarr=new Object[0];
//添加一个元素到数组中        方法是:建立一个新的,比原数组的大小大一的数组,取代原数组。
public void add(Object obj) {
Object[] arr=new Object[oarr.length+1];
for(int i=0;i<oarr.length;i++){
arr[i]=oarr[i];
}
arr[arr.length-1]=obj;
oarr=arr;
}

//添加一组数据到数组中
public void add(Object[] objg){
int k=0;
Object[] arr=new Object[oarr.length+objg.length];
for(int i=0;i<oarr.length;i++){
arr[i]=oarr[i];
k=i;
}
//注意这里k的处理,是因为在测试时出现的不同的错误而进行的修改,虽然有点繁琐,但再没报错了,现在有更好的方法,努力寻找中...
if(k==0)k=-1;
System.out.println(k);
for(int i=0;i<objg.length;i++){
arr[k+i+1]=objg[i];
}
oarr=arr;
}

//指定一个位置,取出一个元素        
public Object get(int index) {
if(index>=0&&index<oarr.length){
Object obj = oarr[index];
return obj;
}
return null;
}

//在指定位置中插入一个元素            方法是:建立一个新的,比原数组大小大一的数组,按顺序将元素安放在新的数组中
public void insert(int index, Object obj) {
Object[] arr=new Object[oarr.length+1];
for(int i=0;i<index;i++){
arr[i]=oarr[i];
}
arr[index]=obj;
for(int i=index;i<oarr.length;i++){
arr[i+1]=oarr[i];
}
oarr=arr;

}

//移除某元素,并将这元素输出                           方法:建立新数组
public Object remove(int index) {
Object[] arr=new Object[oarr.length-1];
for(int i=0;i<index;i++){
arr[i]=oarr[i];
}
Object obj=oarr[index];
for(int i=index+1;i<oarr.length;i++){
arr[i-1]=oarr[i];
}
oarr=arr;
return obj;
}

//取得数组的大小
public int size() {

return oarr.length;
}

//给定一个确切的值,并输出其位置           假设数组中的数都不相同。若果该数不在数组内,则输出-1;
public int find(Object obj){
int target=-1;
for(int i=0;i<oarr.length;i++){
if(oarr[i].equals(obj)){
target=i+1;
}
}
return target;
}

//选出顺序表中的最小值
public int min(){
Integer min=(Integer)oarr[0];
for(int i=1;i<oarr.length;i++){
if(min>(Integer)oarr[i]){
min=(Integer)oarr[i];
}
}
return min;
}

//将数组输出
public void paint(){
for(int i=1;i<=oarr.length;i++){
System.out.print(i+":"+(Integer)oarr[i-1]+"   ");

//想在输出了五个数之后转行            实现的方法:1.增加一个计数器       2.利用i,一旦i为4的倍数,则转行
if(i%4==0)System.out.println();
}
if(oarr.length%4!=0)
System.out.println();
}
}


数组队列的应用例子:
五子棋中棋子摆放位置的记录。
在五子棋的鼠标监听器中
public class ChessAction implements MouseListener{
    Graphics gp;
    Boolean isBlack=true;
    int x1,y1,count=0;
    //定义一个数组来保存信息!
    Shape[] arrShapes=new Shape[100];
   
    public ChessAction(Graphics gp){
    this.gp=gp;
    } 
public void mouseClicked(MouseEvent e) {
ChessSpot cs=new ChessSpot();
cs.setX1(e.getX());
cs.setY1(e.getY());
if(isBlack){
gp.setColor(Color.black);
cs.setColor(Color.black);
isBlack=false;
}else{
gp.setColor(Color.white);
cs.setColor(Color.white);
isBlack=true;
}
//利用数组来保存五子棋的坐标信息
arrShapes[count++]=cs;
gp.fillOval(e.getX()-20,e.getY()-20,40,40);
}
}


链表:
链表和数组储存最大的一个区别就是,链表节点中除了数据,还包含了下一个节点的位置。这使得我们对链表上的数据查找这个过程方便很多。
链表节点的定义:
public class LinkNode {
public Object data;
public LinkNode next;}
创建链表:
public class CreatLink {
    private LinkNode root;
    private LinkNode tail;
    private int lastpos;
    private int count=0;
    //添加一个元素
    public void add(Object obj){  
    if(null==root){
            root=new LinkNode();
    root.data=obj;
    tail=root;
    }
    else{
    LinkNode nn=new LinkNode();
    nn.data=obj;
    tail.next=nn;
    tail=nn;
    }
    count++;
    }
   
   
    //添加一系列节点
    public void add(Object[] object){
    if(null==root){
    LinkNode[] nng=new LinkNode[object.length];
    root=new LinkNode();
    root.data=object[0];
    nng[0]=root;
    tail=root;
    count++;
    for(int i=1;i<object.length;i++){
    nng[i]=new LinkNode();
    nng[i].data=object[i];
    nng[i-1].next=nng[i];
    tail=nng[i];
    count++;
    }
   
    }
    }
   
    //删除节点
    public void remove(int index){
    if(index>=1){
        int i=0;
    LinkNode m=root;
    LinkNode target=root;
    while(i<index-2){
    target=m.next;
    m=m.next;
    i++;
    }  
    target.next=target.next.next;
    }   
    }
   
    //取得位置为index上的节点数据
    public Object get(int index){
    if(index>=1){
    int i=1;
    LinkNode m=root;
    LinkNode target=root;
    while(i<index){
    target=m.next;
    m=m.next;
    i++;
    }   
    return target.data;
    }
    else return -1;
   
    }
    //取得链表长度
    public int size(){
    return count;   
    }
    //输出链表
    public void printLink(){
    LinkNode tem=root;
    int no=0;
    while(tem!=null){
    Object data=tem.data;
    no++;
    System.out.println("data"+no+" is:"+data);
    tem=tem.next;
    }
    }
}



哈弗曼树:
哈弗曼树的节点定义:
public class HfmNode {
//节点的数据
      int data;
      //节点的编码
      String code="";
      //节点的左右孩子
      HfmNode left,right;
}

public class HfmTree {
public static void main(String[] args){
int[] a={4,2,1};
HfmTree ht=new HfmTree();
ht.print(ht.creatTree(a));

}


建立哈弗曼树:
public HfmNode creatTree(int[] a){
//先将数组中的数据传进新建的节点
HfmNode[] nodes=new HfmNode[a.length];
for(int i=0;i<a.length;i++){
HfmNode node=new HfmNode();
node.data=a[i];
nodes[i]=node;
}

//循环建树
while(nodes.length>1){
//对节点数组进行排序
sort(nodes);

System.out.println("here");

           
//取出排序后的节点数组的前两个节点,即是数组中数值最小的两个
HfmNode n1=new HfmNode();
n1=nodes[0];
HfmNode n2=new HfmNode();
n2=nodes[1];

//为刚刚取出的两个节点建立父节点
HfmNode n3=new HfmNode();
            n3.data=n1.data+n2.data;
            n3.left=n1;
            n3.right=n2;
System.out.println("n3="+n3.data);

            //建立新的数组,这个数组里面取出了刚刚的最小的两个节点,并把新的父节点输入
            HfmNode[] nodes2=new HfmNode[nodes.length-1];
            for(int i=0;i<nodes2.length-1;i++){
            nodes2[i]=nodes[i+2];
            }
            nodes2[nodes2.length-1]=n3;
            //用新数组覆盖旧数组
            nodes=nodes2;
}
HfmNode root=new HfmNode();
root=nodes[nodes.length-1];
return root;

}

//对节点数组进行排序
public void sort(HfmNode[] nodes){
for(int i=0;i<nodes.length;i++){
for(int j=i+1;j<nodes.length;j++){
if(nodes[i].data>nodes[j].data){
HfmNode tem=new HfmNode();
tem=nodes[i];
nodes[i]=nodes[j];
nodes[j]=tem;
}
}
}
//测试,将节点数组输出
        for(int i=0;i<nodes.length;i++){
        System.out.print(nodes[i].data+"  ");
        }

}
//对哈夫曼树进行编码,并将编码输出
public void print(HfmNode node){
if(node.left==null&&node.right==null){
System.out.println(node.data+"的哈弗曼编码为:"+node.code);
}
if(node.left!=null){
node.left.code=node.code+"0";
print(node.left);
}
if(node.right!=null){
node.right.code=node.code+"1";
print(node.right);
}
}

}

不管是创建数组、链表还是树,其实我觉得,最重要是我们的逻辑清晰,对数组、链表还有树的定义理解透彻,在编写代码是,难免会出现错误,我会努力尝试自己一个人找出错误。我觉得,自己找自己的错误是一个很好的学习机会,但是在找到错误之后,一定要总结一番。不然,即使改错了,但自己也不一定知道错了什么,最好就能找同学朋友讨论一番。

你可能感兴趣的:(java,数据结构)