android & java面试常问数据结构(数组 链表)和算法题

数据结构相关
数组与链表的的特点:

:数组申请的内存地址是连续的,而链表不需要连续的内存地址,链表所添加的对象的地址是随机的,链表中的每个节点拥有着下一个节点的引用,从而连缀成一条链表。

:数组在创建的时候就已经固定大小,链表不需要指定大小

:数组可以通过下标来随机访问特定的对象,链表只能从表头遍历访问,这就造成数组的访问的效率特别高,而链表的随机访问效率低

:数组的插入和删除操作效率低,因为需要移动其他位置上的对象,链表的插入和删除操作效率高,因为它只需要改变下指针的引用就可以删除或添加对象

链表的简单实现

public class SingleLink {
    Node head = null; // 头节点

    /**
     * 链表中的节点,data代表节点的值,next是指向下一个节点的引用
     */
    static class Node {
        Node next = null;// 节点的引用,指向下一个节点
        int data;// 节点的对象,即内容

        public Node(int data) {
            this.data = data;
        }
    }
    
//添加节点
  public void addNode(int d) {
        Node newNode = new Node(d);// 实例化一个节点
        if (head == null) {
            head = newNode;
            return;
        }
        //尾部插入
      /*
      
        Node tmp = head;
        //找到最后的一个节点
        while (tmp.next != null) {
            tmp = tmp.next;
        }
        //把尾节点的指针指向新创建的节点
        tmp.next = newNode;
	*/
        


      //头部插入
      newNode.next=head;
        head=newNode;
    }

//反转链表
  public void reverse(){
        if(length()<2)return;
        Node curNode=head;
        Node nextNode;
        Node temp = null;
        while (curNode!=null){
                nextNode=curNode.next;
                if(nextNode==null){
                    head=curNode;
                }
                curNode.next=temp;
                temp=curNode;
                curNode=nextNode;

        }

  public static void main(String[] args) {
        SingleLink list = new SingleLink();
        list.addNode(5);
        list.addNode(5);
        list.addNode(3);
        list.addNode(1);
        list.addNode(2);
        list.addNode(2);
        list.addNode(55);
        list.addNode(36);
        list.addNode(36);
        list.printList();
    }
    }

打印结果  :
表头插入
36
36
55
2
2
1
3
5
5

表尾插入
5
5
3
1
2
2
55
36
36

Process finished with exit code 0

经典面试题:反转链表

//从头结点开始遍历,遍历过程中,把每个节点的指针改为指向前一个节点,
  public void reverse(){
        if(length()<2)return;
        Node curNode=head;
        Node nextNode;
        Node temp = null;
        while (curNode!=null){
                nextNode=curNode.next;
                //当遍历到最后一个节点的时候,把它设为头节点
                if(nextNode==null){
                    head=curNode;
                }
                //把当前的节点的指针指向前一个节点
                curNode.next=temp;
                temp=curNode;
                curNode=nextNode;
        }

调用:

反转前
   SingleLink list = new SingleLink();
      	list.addNode(1);
        list.addNode(2);
        list.addNode(3);
        list.addNode(4);
        list.addNode(5);
        list.printList();
打印:
1
2
3
4
5
Process finished with exit code 0


反转后
    SingleLink list = new SingleLink();
        list.addNode(1);
        list.addNode(2);
        list.addNode(3);
        list.addNode(4);
        list.addNode(5);
        list.reverse();
        list.printList();
 打印
5
4
3
2
1

Process finished with exit code 0

常用算法
排序:
1.冒泡排序 (效率低)

   /*
    * 冒泡排序
    * 原理:在遍历的过程中用当前位置的值和下一个值作比较,大于就交换位置,这样一次遍历完之后就把最大的值放到的最后的位置,再次遍历就会把第二大的值放到倒数第二的位置,以此类推
    * */
    public void bubbleSort(int[] arry){
        int length=arry.length;
        int temp;
        for (int i = 0; i < length-1; i++) {
            for (int j = 0; j < length-i-1; j++) {
               if(arry[j]>arry[j+1]){
                   temp=arry[j];
                   arry[j]=arry[j+1];
                   arry[j+1]=temp;
               }
            }
        }
    }

2.插入排序 (效率低)

/*
 * 插入排序
 * 原理:将数组分为两部分,将后部分元素逐一与前部分元素比较,如果前部分元素比array[i]小,就将前部分元素往后移动。当没有比array[i]小的元素,即是合理位置,在此位置插入array[i]
 * */
public void insertSort(int array[]){
  int t,j;
    for (int i =1; i < array.length; i++) {
       if(array[i]<array[i-1]){
           t=array[i];
           for ( j=i-1;j>=0 && t<array[j];j--) {
                array[j+1]=array[j];
           }
           array[j+1]=t;
       }
    }
}

3.快速排序 (效率高)

  /**
     * 快速排序
     * (时间复杂度为nlogn) 
     * */
    public void quickSort(int array[], int low, int high) {// 传入low=0,high=array.length-1;

       int key,v=low,temp;
       if(low<high){
       //选取最左边的值为key
           key=array[low];
           //从左边第二个开始遍历
           for (int i =low+1; i < array.length; i++) {
         	  //当发现小于key的时候,把它移到左边去
               if(array[i]<key){
                   v++;
                   temp=array[v];
                   array[v]=array[i];
                   array[i]=temp;
               }
           }
           //把最后一个小于key的值的位置与key的位置调换,这样key左边的都是小于key,右边的都是大于key的了
           temp=array[v];
           array[v]=key;
           array[low]=temp;
           //然后分别对key左边和右边的分别使用递归来排序
           quickSort(array,low,v-1);
           quickSort(array,v+1,high);
       }
       
    }

查找

二分查找算法:
1.递归法:

  /*
    * 二分查找
    * 递归
    * */
    public int index(int[] array,int key,int low,int high){
        if(key<array[low] || key>array[high] || low>high)return -1;
        if(array[(low+high)/2]>key){
            return index(array,key,low,((low+high)/2)-1);
        }else if(array[(low+high)/2]<key){
            return index(array,key,((low+high)/2)+1,high);
        }else return (low+high)/2;
    }

2.非递归法:


    /*
    * 二分查找
    * 非递归      
    * */
    public int index1(int[] array,int key,int low,int high){
        if(key<array[low] || key>array[high] || low>high)return -1;
        int index=0;
        int moddle;
        while (low<=high){
             moddle=(low+high)/2;
            if(key>array[moddle]){
                low=moddle+1;
            }else if(key<array[moddle]){
                high=moddle-1;
            }
            else return moddle;
        }
        return index;


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值