数据结构练习-java

 

试题1:图两点最短距离
网图中两点之间的最短距离可以通过Dijkstra算法进行计算,通过该算法能够计算出从源点到该图所有顶点的最短距离,给你的问题是:通过DSjar.jar归档文件提供的使用邻接矩阵存储的图对象,计算图中任意两顶点之间的最短距离和路径。 利用类库中的MGraph的参考代码如下:
MGraph mg=new MGraph();//创建的图已经实例化了该图的邻接矩阵,你可以通过输出该矩阵进行查看
输入:标准输入,输入一行有两个正整数,分别表示起点和终点的两个顶点的序号,如果网图有5个顶点,序号从0到4。
输出:标准输出,输出格式为"A-->E distance 90path:A-->B-->E",其中,A为源点顶点名,E为终点顶点名,90为A到E的最短距离,A-->B-->E为路径。
测试用例输入:
0 4
测试用例输出:
A-->E distance 90 path:A-->B-->E

 

importjava.util.Scanner;

importjava.util.Stack;

importhhxy.jsj.graphic.MGraph;

 

public classMyDijkstra {

   private final static intMAXSIZE=10000;

   public static voidmain(String[] args) {

      // TODO Auto-generated method stub

      MGraph g=new MGraph(7,10,false);

      Scanner in=newScanner(System.in);

      int[] p=new int[7];

      int[] d=new int[7];

      int i=in.nextInt();

      int j=in.nextInt();

      GraphTool.shortestpath(g,p,d,i);

      GraphTool.pntshortestpath(g,p,d,i,j);

    }

}

classGraphTool { 

   private final static intMAXSIZE=10000;

   public static voidshortestpath(MGraph g, int[] p, int[] d, int i) {

      // TODO Auto-generated method stub

      int[] flag=new int[g.vexnum];

      p[i]=-1;flag[i]=1;d[i]=0;

      for(intk=0;k<g.vexnum;k++){

         if(k!=i){

            d[k]=g.edges[i][k];

            p[k]=i;

         }

      }

      for(intn=1;n<g.vexnum;n++){

         intmin=MAXSIZE;

         int j=0;

         for(intk=0;k<g.vexnum;k++){

            if(flag[k]==0&&d[k]<min){

                min=d[k];

                j=k;

            }

         }

         flag[j]=1;

         for(intk=0;k<g.vexnum;k++){

                if((flag[k]==0)&&(min+g.edges[j][k])<d[k]){

                   d[k]=min+g.edges[j][k];

                  p[k]=j;

                }

         }

        

      }

   }

   public static voidpntshortestpath(MGraph g, int[] P, int[] D, int i, intj){

          Stack<Integer> st=newStack<Integer>();

          System.out.print(g.vexs[i].vname+"-->:"+g.vexs[j].vname+"diatance "+D[j]+" path:");

          int k=j;

         while(P[k]!=-1){//将数组数据压站

            st.push(P[k]);

            k=P[k];

         }

         while(!st.isEmpty()){

            k=st.pop();

            System.out.print(g.vexs[k].vname+"-->");

         }

         System.out.println(g.vexs[j].vname);   

   }

 

}

 

 

试题2:图的存储实现
图的存储方式有邻接矩阵和邻接表两种基本存储方式,通过给你提供一个图的邻接矩阵存储对象,该对象的邻接矩阵已经赋值;请你将该图的邻接矩阵转换为邻接表存储的图对象,图的对象类型在提供给你的DSjar.jar归档文件中;你可以利用提供的库对象完成本题目的操作,在创建邻接表时,要求从编号小到大的顶点的边进行后插入,如果是无向图,也同样从编号小的顶点到编号大的顶点连接的边进行尾部插入。在MGraph对象中,已经存储了图的相关信息,创建该对象的方法如下:
MGraph mg=new MGraph();
通过该对象可以获得图的顶点、边等信息,然后利用获得的信息新建一个邻接表图对象。调用图对象的打印方法(pntALGraph())实现图的存储信息的输出。
流程控制如下:
MGraph mg=new MGraph();//创建邻接矩阵对象
int vexnum=mg.vexnum;//获得顶点数目
int edgenum=mg.edgenum;//获得边数目
boolean isdirection =mg.isdirection;//是否为有向图
ALGraph alg=new ALGraph(vexnum,edgenum,isdirection);//创建邻接表图对象
//给顶点结点数组赋值
for(int i=0;i<vexnum;i++){
alg.vextex[i]=new VexNode(mg.vexs[i]);
}
EdgeNode p=null;
//建立邻接表边链表
for(int i=0;i<vexnum;i++){
for(int j=0;j<vexnum;j++){
int w=mg.edges[i][j];
if(w>0&&w<1000){
//使用尾插入建立单链表代码
}
}
}
//输出邻接表图存储示例图
alg.pntALGraph();

输入:没有输入。
输出:输出图的邻接表,依据顶点的次序每行输出一个顶点的邻接表信息。
测试用例:
输入:无
输出(仅参考,非正确结果):
1-->[1,20,^]
2-->[2,45,-]-> [0,23,^]
3 ^

 

 

importhhxy.jsj.graphic.MGraph;

import hhxy.jsj.graphic.Vex;

 

public class ALGraph {

    public static voidmain(String[] args){

        MGraph mg=new MGraph(7,10,false);

        int vexnum=mg.vexnum;

        int edgenum=mg.edgenum;

        boolean isdirection =mg.isdirection;

        tALGraph alg=new tALGraph(vexnum,edgenum,isdirection);

        for(int i=0;i<vexnum;i++){

            alg.vextex[i]=new VexNode(mg.vexs[i]);

        }

        EdgeNode p=null;

        for(int i=0;i<vexnum;i++){

           for(int j=0;j<vexnum;j++){

                int w=mg.edges[i][j];

                if(w>0&&w<1000){

                p=alg.vextex[i].firstedge;

                    if(p==null){

                        alg.vextex[i].firstedge=new EdgeNode(j,w);

                    }else{

                        while(p.next!=null)p=p.next;

                        p.next=new EdgeNode(j,w);

                    }

                }

            }

        }

        alg.pntGraph();             

    }  

}

class tALGraph{

    VexNode[] vextex;

    int vexnum;

    int edgenum;

    boolean isdirection;

    EdgeNode p;

    public tALGraph(int vexnum,int edgenum,boolean isdirection){

    this.vexnum = vexnum;

    this.edgenum = edgenum;

    this.isdirection = isdirection;

    vextex=new VexNode[vexnum];//分配空间

    }

    public void pntGraph(){

        for(int i=0;i<vexnum;i++){

            System.out.print(i);//输出顶点名

            //完善代码  输出每个顶点的链表

            p=vextex[i].firstedge;

            int n=0;

            while(p!=null){

                if(n==0)

                   System.out.print("-->["+p.adjvexindex+","+p.data+",");

                else

                   System.out.print("-]->["+p.adjvexindex+","+p.data+",");

                   p=p.next;

                n++;

            }

            if(n!=0){

                System.out.println("^]");

            }else{

                System.out.println("^");

            }

           

        }

    }  

}

class VexNode {

    hhxy.jsj.graphic.Vex vex;

    EdgeNode firstedge;//顶点的邻接边

    VexNode(hhxy.jsj.graphic.Vex vexs){

        this.vex=vexs;

        firstedge=null;//wei kong

    }

}

class EdgeNode {

    int adjvexindex;//邻接顶点的序号

    int data;//边的权值

    EdgeNode next;

    public EdgeNode(int adj,int data){//i,j,w

        next=null;

        adjvexindex=adj;//j

        this.data = data;//w

    }    

}

 

 

 

试题1:哈夫曼树的实现

哈夫曼树也称为最优二叉树,是指对于一组有确定权值的叶结点、构造的具有最小带权路径长度的二叉树。给你的问题是,提供一组n个整数权值,请你完成构建该组权值的哈夫曼树。
输入:标准输入,输入的第一行为一个正整数,其值代表需要构建二叉树的叶结点的个数n;输入的第二行为n个由一个空格隔开的正整数,表示叶结点的权值;输入的第三行为n个字符,对应第二行的权值的叶结点的名称;
输出:标准输出,输出构建的哈夫曼树的每个叶结点的访问路径,即从根到叶结点的路径,如果是走左输出l,如果走右输出r。每行输出一个叶结点信息,输出格式为:先输出该结点的名称,再输出冒号,接下来,输出路径,中间仅一个空格隔开。按照输入叶结点的名称次序分别使用n行输出。
测试样例:
输入:
4
7 5 3 1
abcd
输出:
a:l
b:r r
c:r l r
d:r l l

说明,为了进行系统判断,在构建哈夫曼树时,要求:
(1)选择两个权值小的结点在构建子树时,小的结点为左子树,较大的为右子树;
(2)如果存在两个权值相同,以出现的顺序依次为左右子树;
提示:
在构建哈夫曼树时,提供设计的结点对象参考如下:
public class HFMTreeNode {
int weight,parent,lchild,rchild;
HFMTreeNode(){
weight=0;
parent=lchild=rchild=-1;
}
}

 

public class HFMTool {      

    public static voidmain(String[] args){

        Scanner in=new Scanner(System.in);

        int l=in.nextInt();

        int[] weight=new int[l];

        for(int i=0;i<l;i++){

            weight[i]=in.nextInt();

        }

        String string=in.next();

        char[] ch1=string.toCharArray();

        int n=ch1.length;

        HFMTreeNode[] hfmtree=new HFMTreeNode[2*n-1];

        for(int i=0;i<2*n-1;i++)hfmtree[i]=new HFMTreeNode();

        for(int i=0;i<n;i++)hfmtree[i].weight=weight[i];     

        createHFMTree(hfmtree,n);

        HFMCodeNode[] hfmcd=new HFMCodeNode[n];

        for(int i=0;i<n;i++)hfmcd[i]=new HFMCodeNode(n);

        createHFMCode(hfmtree,hfmcd);           

        for(int i=0;i<n;i++){   

             System.out.print(ch1[i]+": ");

             for(int j=hfmcd[i].start+1;j<n;j++){

                  if(hfmcd[i].bit[j]==0)

                     System.out.print("l ");

                  else

                   System.out.print("r ");

                     }

                System.out.println();

             }          

    }  

    public static void createHFMCode(HFMTreeNode[]hfmtree,HFMCodeNode[] cd){

        int n=cd.length;

        for(int i=0;i<n;i++){

            int c=i;

            int p=hfmtree[i].parent;

            while(p!=-1){

                if(hfmtree[p].lchild==c){

                    cd[i].bit[cd[i].start]=0;

                   

                }else if(hfmtree[p].rchild==c){

                    cd[i].bit[cd[i].start]=1;

                }

                cd[i].start--;

                c=p;

                p=hfmtree[c].parent;

            }

           

        }

    }

    public static voidcreateHFMTree(HFMTreeNode[] hfmtree,int n){

        int x1,x2;

        int m1,m2;

        for(int i=0;i<n-1;i++){

            x1=x2=10000;

            m1=m2=0;

            for(int j=0;j<n+i;j++){

                if(hfmtree[j].parent==-1 && hfmtree[j].weight<x1){

                    x2=x1;

                    m2=m1;

                    x1=hfmtree[j].weight;

                    m1=j;

                   

                }else if(hfmtree[j].parent==-1 && hfmtree[j].weight<x2){

                    x2=hfmtree[j].weight;

                    m2=j;

                }

               

            }

            hfmtree[n+i].weight=x1+x2;

            hfmtree[n+i].lchild=m1;

            hfmtree[n+i].rchild=m2;         

            hfmtree[m1].parent=n+i;

            hfmtree[m2].parent=n+i;

        }

    }

 

}

class HFMTreeNode {

    int weight,parent,lchild,rchild;

    HFMTreeNode(){

        weight=0;

        parent=lchild=rchild=-1;

    }

}

class HFMCodeNode {

    int[] bit;

    int start;

    HFMCodeNode(int n){

        bit=new int[n];

        start=n-1;

    }

}

 

试题2:二叉树的遍历
给你一颗已经创建完成的二叉树,请你根据要求完成该树的遍历实现。提供给你的使用归档文件DSjar.jar,该文件包含了二叉树需要使用的类型和栈队列等相关类型,并提供了一个创建树的静态方法,你可以使用该类库来创建树并完成树的遍历,遍历代码需要你自己设计完成,能提供你的仅为一个创建好的二叉树,二叉树的节点数据类型为Character,该树的创建代码如下:
LinkBiTree<Character> tree =new LinkBiTree<Character>();
LinkBiTree.create(tree);
你通过提供的引用tree完成该树的遍历,遍历可以使用递归和非递归实现。建议你在创建的对象文件中定义如下4种遍历的静态方法,然后根据需要进行调用:
static void PreOrder(LinkBiTree<Character> tree){ //先序遍历

}

static void InOrder(LinkBiTree<Character> tree){ //中序遍历

}

static void PostOrder(LinkBiTree<Character> tree){ //后序遍历

}

static void levelOrder(LinkBiTree<Character> tree){//层次遍历

}
输入:标准输入,输入为由一个空格分隔开的4个整数,其中1表示先序遍历,2表示中序遍历,
3表示后序遍历,4表示分层遍历。
输出:标准输出,根据输入的要求,各种遍历使用一行输出,每个顶点的数据为字符,字符之间使用
一个空格分开。
测试用例:
输入:
1 2 3 4
输出(非正确输出,仅参考格式):
A B C
B A C
B C A
A B C

 

public classBiTreeSearch {

    public static voidmain(String[] args) {

        int[] a=new int[4];

        LinkBiTree<Character> tree =newLinkBiTree<Character>();

        LinkBiTree.create(tree);

        Scanner in=newScanner(System.in);

        for(int i=0;i<4;i++){

            a[i]=in.nextInt();

        }

        for(int i=0;i<4;i++){

            int j=a[i];

            switch(j){

             case 1:PreOrder(tree.root);break;

             case 2:InOrder(tree.root);break;

             case 3:PostOrder(tree.root);break;

             case 4:levelOrder(tree.root);break;

            }

            System.out.println();

        }  

    }

    static void PreOrder(LinkNodep){ //先序遍历

          if(p==null)return;

          System.out.print(p.data+"");

          PreOrder(p.lchild);

          PreOrder(p.rchild);

    }

    static void InOrder(LinkNodep){ //中序遍历

        if(p==null) return;

        InOrder(p.lchild);

         System.out.print(p.data+"");

        InOrder(p.rchild);

    }

 

    static void PostOrder(LinkNodep){ //后序遍历

        if(p==null)return;

        PostOrder(p.lchild);

        PostOrder(p.rchild);

        System.out.print(p.data+""); 

    }

 

    static<E> voidlevelOrder(LinkNode root){//层次遍历

       if(root==null)return;

      Queue<LinkNode<E>> q=newLinkedList<LinkNode<E>>();

        q.add(root);

        while(!q.isEmpty()){

            LinkNode<E> p=q.poll();

            System.out.print(p.data+"");

            if(p.lchild!= null){

                q.add (p.lchild);

            }

            if(p.rchild!= null){

                q.add (p.rchild);

           }

         }

     }

}

 

 

classLinkBiTree<E>{

    LinkNode<E> root=null;

    public static voidcreate(LinkBiTree<Character> tree){

        tree.create('A', null, null);

        tree.insertL(tree.root, newLinkNode('B'));

        tree.insertR(tree.root, newLinkNode('C'));

    }

    public void create(E val,LinkNode<E> l, LinkNode<E> r) {

        root = new LinkNode(val,l,r);

    }

    public voidinsertL(LinkNode<E> node, LinkNode<E> p) {

        if(node!=null){

            node.lchild = p;

        }

       

    }

    public voidinsertR(LinkNode<E> node, LinkNode<E> p) {

        if(node!=null){

            node.rchild = p;

        }  

    }

}

classLinkNode<E>{

    E data;

    LinkNode<E> lchild,rchild;

    LinkNode(E data,LinkNode<E>l,LinkNode<E> r){

        this.data =data;

        this.lchild = l;

        this.rchild = r;

    }

    LinkNode(E data){

        this.data =data;

        this.lchild = null;

        this.rchild = null;

    }

}

 

 

试题1:折半查找
折半查找是在有序表中,把待查找数据值与查找范围的中间元素值进行比较,会有三种情况出现:
1)待查找数据值与中间元素值正好相等,则放回中间元素值的索引。
2)待查找数据值比中间元素值小,则以整个查找范围的前半部分作为新的查找范围,执行1),直到找到相等的值。
3)待查找数据值比中间元素值大,则以整个查找范围的后半部分作为新的查找范围,执行1),直到找到相等的值
4)如果最后找不到相等的值,则返回不存储数据的备用单位0。
给你的问题是,标准输入一升序排列有序整数表,使用折半查找方法查找一个给定的整数值,查找中是通过使用表中的元素与给定的元素值进行比较完成查找,需要你依次输出在折半查找过程中使用过比较的元素值。
输入:标准输入,输入的第一行为一个正整数n,表示需要查找表的元素个数;第二行为具有升序序列的n个整数,两数之间为一个空格隔开;第三行为需要你查找的整数。
输出:标准输出,第一行依次输出在查找过程中进行比较的元素值,两数之间使用一个空格隔开。输出的第二行输出查找结果,如果查找元素在表中,输出该元素的序号(从1开始编号),如果查找元素不在表中,输出“NO"。
输入样例:
13
7 14 18 21 23 29 31 35 38 42 46 49 52
21
输出样例:
31 18 23 21
4

 

public classZebanchazhao {

    public static voidmain(String[] args) {

            int n,l;

            int []data;

            Scanner in=newScanner(System.in);

           n=in.nextInt();

           data=new int [n];

           for(int i=0;i<n;i++)data[i]=in.nextInt();

           l=in.nextInt();

          System.out.println(binSearch(data,l));    

     }

     privatestatic int binSearch(int[] data,int key) {

            int low =0,high=data.length-1,mid;

            while(high>=low){           

                mid=(low+high)/2;

                System.out.print(data[mid]+"");

                if(key==data[mid]){

                    System.out.println();

                    return mid+1;

                }else if(key>data[mid])

                    low=mid+1;

                else high=mid-1;           

            }

            System.out.println();

            return 0;

        }

}

 

 

试题2:堆排序
堆排序的思想实际上利用完全二叉树存储在数组中,通过调整完全二叉树成为大顶堆获得一个排序表的最大值进行排序的方法,大顶堆满足根节点比子树旳节点大。堆排序主要是通过大顶堆旳根元素与未完成排序旳最后一个元素进行交换,将交换后旳完全二叉树不满足大顶堆要求调整到满足满足要求,调整通过如下方法完成:
void heapAdjust(int[] R,int s,int t);其中,数组R中存储旳二叉树,只有以R[s]为根子树,其左右子树之间可能不满足大顶堆特征。
调整堆旳操作难点为根子树节点编号为i,则左子树节点编号为2*i,右子树节点编号为2*i+1;通过比较子树旳大小选择大旳子树进行调整,一直调整到根节点比子节点大,再将根节点旳值插入到最后调整旳节点。要完成堆排序,在调整旳基础上可以通过从堆底往堆顶进行调整获得初始堆,然后通过N-1次调整完成排序,控制流程为:
void heapSort(int[] R){
int i;
int N=R.length-1;
for(i=N/2;i>0;i--){
heapAdjust(R,i,N);
}
for(i=N;i>1;i--){
R[0]=R[1];R[1]=R[i];R[i]=R[0];
heapAdjust(R,1,i-1);
}
}
给你旳问题是,将标准输入的n个整数采用堆排序,并需要显示建成旳初始堆,并完成该数据的排序。
输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之间为一个空格。
输出:标准输出,第一行依次输出排序过程中建成旳初始堆在数组中的存储值,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。
输入样例:
14
39 80 76 41 13 29 50 78 30 11 100 7 41 86
输出样例:
100 80 86 78 39 41 76 41 30 11 13 7 29 50
7 11 13 29 30 39 41 41 50 76 78 80 86 100

 

public classdui {

    public static voidmain(String[] args) {

        int n;int[] data;

        Scanner in=new Scanner(System.in);

        n=in.nextInt();

        data=new int[n];

        for(int i=0;i<n;i++)

            data[i]=in.nextInt();

        heapSort(data,0,data.length-1);

        for(int i=0;i<n;i++)

            System.out.print(i!=n-1?data[i]+"":data[i]);

        System.out.println();

        in.close();

    }

    public static voidheapSort(int[] data,int low,int high){

        int i,top;

        int N=data.length-1;

        for(i=N/2;i>=0;i--){//创建初始堆

             siftdown(data,i,N);

        }

        for(i=0;i<=N;i++)

            System.out.print(i!=N?data[i]+"":data[i]);  

        System.out.println();

        for(i=N;i>0;i--){

        //取出堆顶元素放在数组的最后面,数组最后的数放在堆顶再向下调整,数组的0位置不用来存储堆数据,用来交换数据的时候暂存数据

             top=data[0];

             data[0]=data[i];

             data[i]=top;      

             siftdown(data,0,i-1);

        }

 

    }

    public static voidsiftdown(int[] data,int low,int high){

    intk=low;

    intj=2*k+1;

    inttemp=data[k];

    while(j<=high){

          //判断右子节点是否存在,并比较左右节点的大小,和最大的交换

          if((j<high)&&(j+1<=high)&&(data[j]<data[j+1]))

              ++j;

          if(temp<data[j]){//调整完之后继续向下调整

               data[k]=data[j];

               k=j;

               j=2*k+1;

          }else{

              break;

          }

    }

    data[k]=temp;//找到该点的合适位置

    }

   

}

 

                                        

  • 试题1:快速排序
    快速排序的核心操作是划分,通过某个数据将原来排序表分成两部分,前面部分比该数小,后面数据比该数据大或相等,该位置就为某数据排序后的位置,即该数据完成排序。如果定义一个排序表的划分方法为:
    int partition(int[] R,int low,int high); 其中,low,high表示将数据R的第low个数据到high个数据进行划分,返回到整数为划分后到支点存储的位置;快速排序在查找分支点位置的方法有多种,本题目的排序过程中,首先从右向左移动,搜索小于分支记录的第一个元素,再从左向右移动,搜索大于分支记录的第一个元素,交互该两个记录值,继续搜索,直到两个搜索点交汇,如果交汇点记录与分支记录相等,分支记录与交汇点数据不交换,分支位置为交汇位置; 完成划分方法后,通过递归调用完成快速排序:
    void QuickSort(int[] R,int s,int t){
    if(s<t){
    int i=partition(R,s,t);
    QuickSort(R,s,i-1);
    QuickSort(R,i+1,t);
    }
    }
    建议每次划分选择第一个元素为支点记录进行编程。给你到问题是,将标准输入的n个整数采用快速排序,并需要显示出每次划分分支点存储的位置,第一个数为0,分支点的输出顺序按照程序递归产生的分支点的先后进行输出,并完成该数据的排序。
    输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之间为一个空格。
    输出:标准输出,输出的第一行依次输出排序过程中使用的支点位置,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。
    输入样例:
    14
    39 80 76 41 13 29 50 78 30 11 100 7 41 86
    输出样例:
    5 3 2 1 8 7 9 13 12 10
    7 11 13 29 30 39 41 41 50 76 78 80 86 100

 

public classQuicksort {

    public static voidmain(String[] args) {

        int n;int[] data;

        Scanner in=newScanner(System.in);

        n=in.nextInt();

        data=new int[n];

        for(int i=0;i<n;i++)

            data[i]=in.nextInt();

        QuickSort(data,0,data.length-1);

        System.out.println();

        for(int i=0;i<n;i++)

            System.out.print(data[i]+"");

        System.out.println();

    }

    public static voidQuickSort(int[] R,int low,int high){

        int base=R[low];

        int i=low+1;

        int j=high;

        int temp;

        while(i<j){

            while((i<j)&&(R[j]>=base))

                --j;

            while((i<j)&&(R[i]<=base))

                ++i;

           

            if(i<j){

                temp=R[i];

                R[i]=R[j];

                R[j]=temp;

            }

        }

        if(i==low+1&&R[i]>R[low]){

              i=low;

              j=low;

        }

        if(R[j]<=R[low]){

            temp=R[low];

            R[low]=R[j];

            R[j]=temp;

        }

        System.out.print(j+"");    

        if(i-low>1)

            QuickSort(R,low,i-1);

        if(high-j>1)

            QuickSort(R,j+1,high);

    }

}

 

试题2:希尔排序

希尔排序的思想是:先选择一个小于排序数据个数n的整数di(称为步长,一般为小于n的质数),将间隔di的数为一组,对每组的元素进行直接插入排序,即将需要排序的数据插入到已经排序好的序列中。当步长为1时,完成整个数据的排序。排序的流程为:
1、根据步长的个数,对于每个步长进行分组;
2、对每组进行插入排序,主要操作如下:
1)如果待插入数据比前一个数据小,将该数据存储到临时遍历temp中;
2)将前面比他大的数据全部向后移动一位;
3)再将temp的数据插入到最后移动的数据位置;
给你到问题是,将标准输入的n个整数采用希尔排序,步长取5,3,1,并需要显示出每次需要插入的数,并完成该数据的排序。
输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之间为一个空格。
输出:标准输出,输出第一行依次输出排序过程中需要插入的数,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。
输入样例:
14
39 80 76 41 13 29 50 78 30 11 100 7 41 86
输出样例:
29 50 30 11 7 41 39 13 86 7 29 11 30 41 50 80 78
7 11 13 29 30 39 41 41 50 76 78 80 86 100

public class xier {

       public static voidmain(String[] args) {

       int[] data;

       int[] d={5,3,1};

       int n;

       Scanner in=newScanner(System.in);

       n=in.nextInt();

       data=new int[n];

       for(inti=0;i<n;i++)data[i]=in.nextInt();

       shellsort(data,d);

       for(int i=0;i<n;i++)

              System.out.print(data[i]+" ");

       System.out.println();

       }

       public static voidshellsort(int[] data,int[] d){

              int h,temp,k,j,p;

              for(k=0;k<3;k++){

                     h=d[k];

                     for(j=h;j<data.length;j++){

                            if(data[j]<data[j-h]){

                                   temp=data[j];

                                   System.out.print(data[j]+" ");

                                   for(p=j;p>=h&&temp<data[p-h];p=p-h){

                                          data[p]=data[p-h];

                                   }

                                   data[p]=temp;

                            }

                     }     

              }

           System.out.println();

       }

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值