日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java面试宝典系列之基础面试题String、变量、类与对象、集合类、SSH(三)

發布時間:2025/3/19 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java面试宝典系列之基础面试题String、变量、类与对象、集合类、SSH(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java面試寶典之數據結構基礎 —— 線性表篇

作者:egg

郵箱:xtfggef@gmail.com

微博:http://weibo.com/xtfggef

博客:http://blog.csdn.net/zhangerqing(轉載請說明出處)

這部分內容作為計算機專業最基礎的知識,幾乎被所有企業選中用來作考題,因此,本章我們從本章開始,我們將從基礎方面對數據結構進行講解,內容主要是線性表,包括棧、隊列、數組、字符串等,主要講解基礎知識,如概念及簡單的實現代碼,非線性結構我們在后面的文章中給出。過程中有任

何問題,請聯系本人:http://weibo.com/xtfggef?


一、數據結構概念

用我的理解,數據結構包含數據和結構,通俗一點就是將數據按照一定的結構組合起來,不同的組合方式會有不同的效率,使用不同的場景,如此而已。比如我們最常用的數組,就是一種數據結構,有獨特的承載數據的方式,按順序排列,其特點就是你可以根據下標快速查找元素,但是因為在數組中插入和刪除元素會有其它元素較大幅度的便宜,所以會帶來較多的消耗,所以因為這種特點,使得數組適合:查詢比較頻繁,增、刪比較少的情況,這就是數據結構的概念。數據結構包括兩大類:線性結構和非線性結構,線性結構包括:數組、鏈表、隊列、棧等,非線性結構包括樹、圖、表等及衍生類結構。本章我們先講解線性結構,主要從數組、鏈表、隊列、棧方面進行討論,非線性數據結構在后面會繼續講解。


二、線性表

線性表是最基本、最簡單、也是最常用的一種數據結構。線性表中數據元素之間的關系是一對一的關系,即除了第一個和最后一個數據元素之外,其它數據元素都是首尾相接的。線性表的邏輯結構簡單,便于實現和操作。因此,線性表這種數據結構在實際應用中是廣泛采用的一種數據結構。其基本操作主要有:

? ?1)MakeEmpty(L) 這是一個將L變為空表的方法
? ?2)Length(L) 返回表L的長度,即表中元素個數?
? ?3)Get(L,i) 這是一個函數,函數值為L中位置i處的元素(1≤i≤n)
? ?4)Prev(L,i) 取i的前驅元素
? ?5)Next(L,i) 取i的后繼元素
? ?6)Locate(L,x) 這是一個函數,函數值為元素x在L中的位置
? ?7)Insert(L,i,x)在表L的位置i處插入元素x,將原占據位置i的元素及后面的元素都向后推一個位置
? ?8)Delete(L,p) 從表L中刪除位置p處的元素
? ?9)IsEmpty(L) 如果表L為空表(長度為0)則返回true,否則返回false
? ?10)Clear(L)清除所有元素
? ?11)Init(L)同第一個,初始化線性表為空
? ?12)Traverse(L)遍歷輸出所有元素
? ?13)Find(L,x)查找并返回元素
? ?14)Update(L,x)修改元素
? ?15)Sort(L)對所有元素重新按給定的條件排序
? ?16) strstr(string1,string2)用于字符數組的求string1中出現string2的首地址

不管采用哪種方式實現線性表,至少都應該具有上述這些基本方法,下面我會將下數據結構的基本實現方式。


三、基礎數據結構

數據結構是一種抽象的數據類型(ADT),可以這么說,我們可以采用任意的方式實現某種數據結構,只要符合將要實現的數據結構的特點,數據結構就是一種標準,我們可以采用不同的方式去實現,最常用的兩種就是數組和鏈表(包括單鏈表、雙向鏈表等)。數組是非常常見的數據類型,在任何一種語言里都有它的實現,我們這里采用Java來簡單實現一下數組。
數組是一種引用類型的對象,我們可以像下面這樣的方式來聲明數組:

  • int a[];
  • int[] b;
  • int []c;
  • a = new int[10];

    總結起來,聲明一個數組有基本的三個因素:類型、名稱、下標,Java里,數組在格式上相對靈活,下標和名稱可以互換位置,前三種情況我們可以理解為聲明一個變量,后一種為其賦值。或者像下面這樣,在聲明的時候賦值:

  • int c[] = {2,3,6,10,99};
  • int []d = new int[10];
  • 我稍微解釋一下,其實如果只執行:int[] b,只是在棧上創建一個引用變量,并未賦值,只有當執行d = new int[10]才會在堆上真正的分配空間。上述第一行為靜態初始化,就是說用戶指定數組的內容,有系統計算數組的大小,第二行恰恰相反,用戶指定數組的大小,由系統分配初始值,我們打印一下數組的初始值:

  • int []d = new int[10];
  • System.out.println(d[2]);
  • 結果輸出0,對于int類型的數組,默認的初始值為0.

    但是,絕對不可以像下面這樣:

    int e[10] = new int[10];無法通過編譯,至于為什么,語法就是這樣,這是一種規范,不用去想它。
    我們可以通過下標來檢索數組。下面我舉個簡單的例子,來說明下數組的用法。

  • public static void main(String[] args) {
  • String name[];
  • name = new String[5];
  • name[0] = "egg";
  • name[1] = "erqing";
  • name[2] = "baby";
  • for (int i = 0; i < name.length; i++) {
  • System.out.println(name[i]);
  • }
  • }
  • 這是最簡單的數組聲明、創建、賦值、遍歷的例子,下面寫個增刪的例子。

  • package com.xtfggef.algo.array;
  • public class Array {
  • public static void main(String[] args) {
  • int value[] = new int[10];
  • for (int i = 0; i < 10; i++) {
  • value[i] = i;
  • }
  • // traverse(value);
  • // insert(value, 666, 5);
  • delete(value, 3);
  • traverse(value);
  • }
  • public static int[] insert(int[] old, int value, int index) {
  • for (int k = old.length - 1; k > index; k--)
  • old[k] = old[k - 1];
  • old[index] = value;
  • return old;
  • }
  • public static void traverse(int data[]) {
  • for (int j = 0; j < data.length; j++)
  • System.out.print(data[j] + " ");
  • }
  • public static int[] delete(int[] old, int index) {
  • for (int h = index; h < old.length - 1; h++) {
  • old[h] = old[h + 1];
  • }
  • old[old.length - 1] = 0;
  • return old;
  • }
  • }
  • 簡單寫一下,主要想說明數組中刪除和增加元素的原理:增加元素,需要將index后面的依次向后移動,然后將值插入index位置,刪除則將后面的值依次向前移動,較簡單。

    要記住:數組是表示相同類型的一類數據的集合,下標從0開始,就行了。

    數組實現的線下表可以參考ArrayList,在JDK中附有源碼,感興趣的同學可以讀讀。下面我簡單介紹下單鏈表。

    單鏈表是最簡單的鏈表,有節點之間首尾連接而成,簡單示意如下:


    除了頭節點,每個節點包含一個數據域一個指針域,除了頭、尾節點,每個節點的指針指向下一個節點,下面我們寫個例子操作一下單鏈表。

  • package com.xtfggef.algo.linkedlist;
  • public class LinkedList<T> {
  • /**
  • * class node
  • * @author egg
  • * @param <T>
  • */
  • private static class Node<T> {
  • T data;
  • Node<T> next;
  • Node(T data, Node<T> next) {
  • this.data = data;
  • this.next = next;
  • }
  • Node(T data) {
  • this(data, null);
  • }
  • }
  • // data
  • private Node<T> head, tail;
  • public LinkedList() {
  • head = tail = null;
  • }
  • /**
  • * judge the list is empty
  • */
  • public boolean isEmpty() {
  • return head == null;
  • }
  • /**
  • * add head node
  • */
  • public void addHead(T item) {
  • head = new Node<T>(item);
  • if (tail == null)
  • tail = head;
  • }
  • /**
  • * add the tail pointer
  • */
  • public void addTail(T item) {
  • if (!isEmpty()) {
  • tail.next = new Node<T>(item);
  • tail = tail.next;
  • } else {
  • head = tail = new Node<T>(item);
  • }
  • }
  • /**
  • * print the list
  • */
  • public void traverse() {
  • if (isEmpty()) {
  • System.out.println("null");
  • } else {
  • for (Node<T> p = head; p != null; p = p.next)
  • System.out.println(p.data);
  • }
  • }
  • /**
  • * insert node from head
  • */
  • public void addFromHead(T item) {
  • Node<T> newNode = new Node<T>(item);
  • newNode.next = head;
  • head = newNode;
  • }
  • /**
  • * insert node from tail
  • */
  • public void addFromTail(T item) {
  • Node<T> newNode = new Node<T>(item);
  • Node<T> p = head;
  • while (p.next != null)
  • p = p.next;
  • p.next = newNode;
  • newNode.next = null;
  • }
  • /**
  • * delete node from head
  • */
  • public void removeFromHead() {
  • if (!isEmpty())
  • head = head.next;
  • else
  • System.out.println("The list have been emptied!");
  • }
  • /**
  • * delete frem tail, lower effect
  • */
  • public void removeFromTail() {
  • Node<T> prev = null, curr = head;
  • while (curr.next != null) {
  • prev = curr;
  • curr = curr.next;
  • if (curr.next == null)
  • prev.next = null;
  • }
  • }
  • /**
  • * insert a new node
  • * @param appointedItem
  • * @param item
  • * @return
  • */
  • public boolean insert(T appointedItem, T item) {
  • Node<T> prev = head, curr = head.next, newNode;
  • newNode = new Node<T>(item);
  • if (!isEmpty()) {
  • while ((curr != null) && (!appointedItem.equals(curr.data))) {
  • prev = curr;
  • curr = curr.next;
  • }
  • newNode.next = curr;
  • prev.next = newNode;
  • return true;
  • }
  • return false;
  • }
  • public void remove(T item) {
  • Node<T> curr = head, prev = null;
  • boolean found = false;
  • while (curr != null && !found) {
  • if (item.equals(curr.data)) {
  • if (prev == null)
  • removeFromHead();
  • else
  • prev.next = curr.next;
  • found = true;
  • } else {
  • prev = curr;
  • curr = curr.next;
  • }
  • }
  • }
  • public int indexOf(T item) {
  • int index = 0;
  • Node<T> p;
  • for (p = head; p != null; p = p.next) {
  • if (item.equals(p.data))
  • return index;
  • index++;
  • }
  • return -1;
  • }
  • /**
  • * judge the list contains one data
  • */
  • public boolean contains(T item) {
  • return indexOf(item) != -1;
  • }
  • }

  • 單鏈表最好玩兒的也就是增加和刪除節點,下面的兩個圖分別是用圖來表示單鏈表增、刪節點示意,看著圖學習,理解起來更加容易!


    接下來的隊列和棧,我們分別用不同的結構來實現,隊列用數組,棧用單列表,讀者朋友對此感興趣,可以分別再用不同的方法實現。


    四、隊列
    隊列是一個常用的數據結構,是一種先進先出(First In First Out, FIFO)的結構,也就是說只能在表頭進行刪除,在表尾進行添加,下面我們實現一個簡單的隊列。

  • package com.xtfggef.algo.queue;
  • import java.util.Arrays;
  • public class Queue<T> {
  • private int DEFAULT_SIZE = 10;
  • private int capacity;
  • private Object[] elementData;
  • private int front = 0;
  • private int rear = 0;
  • public Queue()
  • {
  • capacity = DEFAULT_SIZE;
  • elementData = new Object[capacity];
  • }
  • public Queue(T element)
  • {
  • this();
  • elementData[0] = element;
  • rear++;
  • }
  • public Queue(T element , int initSize)
  • {
  • this.capacity = initSize;
  • elementData = new Object[capacity];
  • elementData[0] = element;
  • rear++;
  • }
  • public int size()
  • {
  • return rear - front;
  • }
  • public void add(T element)
  • {
  • if (rear > capacity - 1)
  • {
  • throw new IndexOutOfBoundsException("the queue is full!");
  • }
  • elementData[rear++] = element;
  • }
  • public T remove()
  • {
  • if (empty())
  • {
  • throw new IndexOutOfBoundsException("queue is empty");
  • }
  • @SuppressWarnings("unchecked")
  • T oldValue = (T)elementData[front];
  • elementData[front++] = null;
  • return oldValue;
  • }
  • @SuppressWarnings("unchecked")
  • public T element()
  • {
  • if (empty())
  • {
  • throw new IndexOutOfBoundsException("queue is empty");
  • }
  • return (T)elementData[front];
  • }
  • public boolean empty()
  • {
  • return rear == front;
  • }
  • public void clear()
  • {
  • Arrays.fill(elementData , null);
  • front = 0;
  • rear = 0;
  • }
  • public String toString()
  • {
  • if (empty())
  • {
  • return "[]";
  • }
  • else
  • {
  • StringBuilder sb = new StringBuilder("[");
  • for (int i = front ; i < rear ; i++ )
  • {
  • sb.append(elementData[i].toString() + ", ");
  • }
  • int len = sb.length();
  • return sb.delete(len - 2 , len).append("]").toString();
  • }
  • }
  • public static void main(String[] args){
  • Queue<String> queue = new Queue<String>("ABC", 20);
  • queue.add("DEF");
  • queue.add("egg");
  • System.out.println(queue.empty());
  • System.out.println(queue.size());
  • System.out.println(queue.element());
  • queue.clear();
  • System.out.println(queue.empty());
  • System.out.println(queue.size());
  • }
  • }
  • 隊列只能在表頭進行刪除,在表尾進行增加,這種結構的特點,適用于排隊系統。

    五、棧

    棧是一種后進先出(Last In First Out,LIFO)的數據結構,我們采用單鏈表實現一個棧。

  • package com.xtfggef.algo.stack;
  • import com.xtfggef.algo.linkedlist.LinkedList;
  • public class Stack<T> {
  • static class Node<T> {
  • T data;
  • Node<T> next;
  • Node(T data, Node<T> next) {
  • this.data = data;
  • this.next = next;
  • }
  • Node(T data) {
  • this(data, null);
  • }
  • }
  • @SuppressWarnings("rawtypes")
  • static LinkedList list = new LinkedList();
  • @SuppressWarnings("unchecked")
  • public T push(T item) {
  • list.addFromHead(item);
  • return item;
  • }
  • public void pop() {
  • list.removeFromHead();
  • }
  • public boolean empty() {
  • return list.isEmpty();
  • }
  • public int search(T t) {
  • return list.indexOf(t);
  • }
  • public static void main(String[] args) {
  • Stack<String> stack = new Stack<String>();
  • System.out.println(stack.empty());
  • stack.push("abc");
  • stack.push("def");
  • stack.push("egg");
  • stack.pop();
  • System.out.println(stack.search("def"));
  • }
  • }

  • 本章的內容都是很基礎的,重在讓讀者朋友們理解數據結構的概念,下章開始,我們會介紹樹、二叉樹等Java中的實現,敬請讀者朋友們持續關注!

    作者:egg

    郵箱:xtfggef@gmail.com

    微博:http://weibo.com/xtfggef

    博客:http://blog.csdn.net/zhangerqing(轉載請說明出處)


    有問題,請依照上述聯系方式聯系作者,歡迎讀者及時提出建議,謝謝! 與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的Java面试宝典系列之基础面试题String、变量、类与对象、集合类、SSH(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。