Java基礎數據結構–線性表
線性表:
線性表是最基本、最簡單、也是最常用的一種數據結構。
線性表中數據元素之間的關係是一對一的關係,即除了第一個和最後一個數據元素之外,其它數據元素都是首尾相接的(注意,這句話只適用大部分線性表,而不是全部。比如,循環鏈表邏輯層次上也是一種線性表(存儲層次上屬於鏈式存儲),但是把最後一個數據元素的尾指針指向了首位結點)。
我們說“線性”和“非線性”,只在邏輯層次上討論,而不考慮存儲層次,所以雙向鏈表和循環鏈表依舊是線性表。
在數據結構邏輯層次上細分,線性表可分爲一般線性表和受限線性表。一般線性表也就是我們通常所說的“線性表”,可以自由的刪除或添加結點。受限線性表主要包括棧和隊列,受限表示對結點的操作受限制。
線性表的邏輯結構簡單,便於實現和操作。因此,線性表這種數據結構在實際應用中是廣泛採用的一種數據結構。
1、定義
-
線性表 *(linear list)*是數據結構的一種,一個線性表是n個具有相同特性的數據元素的有限序列。數據元素是一個抽象的符號,其具體含義在不同的情況下一般不同。
-
注:線性表的相鄰元素之間存在着序偶關係。如用(a 1,…,a i-1,a i,a i+1,…,a n)表示一個順序表,則表中a i-1領先於a i ,a i領先於a i+1,稱a i-1是a i的直接前驅元素,a i+1是a i的直接後繼元素。當i=1,2,…,n-1時,a i有且僅有一個直接後繼,當i=2,3,…,n時,a i有且僅有一個直接前驅 。
2、存儲結構
線性表主要由順序表示或鏈式表示。在實際應用中,常以 棧、 隊列、 字符串等特殊形式使用。
順序表示指的是用一組地址連續的存儲單元依次存儲線性表的數據元素,稱爲線性表的順序存儲結構或順序映像 (sequential mapping)。它以“物理位置相鄰”來表示線性表中數據元素間的邏輯關係,可隨機存取表中任一元素。
鏈式表示指的是用一組任意的存儲單元存儲線性表中的數據元素,稱爲線性表的鏈式存儲結構。它的存儲單元可以是連續的,也可以是不連續的。在表示數據元素之間的邏輯關係時,除了存儲其本身的信息之外,還需存儲一個指示其直接後繼的信息 (即直接後繼的存儲位置),這兩部分信息組成數據元素的存儲映像,稱爲結點*(node)*。它包括兩個域;存儲數據元素信息的域稱爲數據域;存儲直接後繼存儲位置的域稱爲指針域。指針域中存儲的信息稱爲指針或鏈 。
1、順序存儲
- 順序表的定義:線性表的順序存儲結構是一組連續的內存單元依次存放的線性表的數據元素,* 元素的物理地址和邏輯地址次序是相同的。我們叫做這種存儲方式爲順序表
- 順序表,使用數組實現,一組地址連續的存儲單元,數組大小有兩種方式指定,一是靜態分配,二是動態擴展。
- 注:線性表從1開始,而數組從0開始。
- 優點:隨機訪問特性,查找O(1)時間,存儲密度高;邏輯上相鄰的元素,物理上也相鄰;
- 缺點:插入刪除需移動大量元素。
- 順序表相關的操作跟數組有關,一般都是移動數組元素。
2、鏈式存儲
- 鏈表的定義是遞歸的,它或者爲空null,或者指向另一個節點node的引用,這個節點含有下一個節點或鏈表的引用。
- 與順序存儲相比,允許存儲空間不連續,插入刪除時不需要移動大量的元素,只需修改指針即可,但查找某個元素,只能從頭遍歷整個鏈表。
- Java中使用嵌套類來定義節點的抽象數據類型:
public class TestLink {
class Node {
int data;
Node next;
public Node() {
this.data = data;
this.next = null;
}
public Node(int val) {
this.data = val;
this.next = null;
}
}
private Node head;
public TestLink() {
this.head = new Node();
}
3、棧、隊列也是一種線性表
棧(Stack)是限定只能在表的一端進行插入和刪除操作的線性表。
隊列(Queue)是限定只能在表的一端進行插入和在另一端進行刪除操作的線性表。
從"數據結構"的角度看,它們都是線性結構,即數據元素之間的關係相同。但它們是完全不同的數據類型。除了它們各自的基本操作集不同外,主要區別是對插入和刪除操作的"限定"。
棧和隊列是在程序設計中被廣泛使用的兩種線性數據結構,它們的特點在於基本操作的特殊性,棧必須按"後進先出"的
規則進行操作,而隊列必須按"先進先出"的規則進行操作。和線性表相比,它們的插入和刪除操作受更多的約束和限定,故又稱爲限定性的線性表結構。可將線性表和棧及隊列的插入和刪除操作對比如下:
線性表
Insert(L,i,x)
(1≤i≤n+1)
Delete(L,i)
(1≤i≤n)
如線性表允許在表內任一位置進行插入和刪除
棧
Insert(L,n+1,x)
Delete(L,n)
而棧只允許在表尾一端進行插入和刪除
隊列
Insert(L,n+1,x)
Delete(L,1)
隊列只允許在表尾一端進行插入,在表頭一端進行刪除
3、順序表代碼實
//順序表的實現
class TestSqlist {
private int[] elem;//存放數據的數組
private int usedsize;//有效數據個數
public TestSqlist() {
this(10);
}//給初始值
public TestSqlist(int size) {
this.elem = new int[size];
}
//開始一系列 增刪,查改操作
/**
* 思想
* 1.判斷如果滿了怎麼辦 this.usedsize == this.elem.length
* 2.如果爲空怎麼辦
* 3.增:因爲一開始沒有數據,所以先增加
*/
//1.判斷如果滿了怎麼辦
public boolean isFull() {
if (this.usedsize == this.elem.length) {
return true;
}
return false;
}
//2.如果爲空怎麼辦
public boolean isEmpty() {
if (this.usedsize == 0) {
return true;
}
return false;
}
//3.插入元素
public boolean insear(int pos, int val) {
if(isFull()) {
this.elem = Arrays.copyOf(this.elem, this.elem.length * 2);
}
//不爲空: pos 可能 < 0 , 可能 pos > this.usedsize
if(pos < 0 || pos > this.usedsize){
return false;
}else{
for(int i = usedsize - 1; i >= pos ; i--){
this.elem[i + 1] = this.elem[i];
}
this.elem[pos] = val;
this.usedsize++;
}
return true;
}
//4.查找關鍵字key下標
public int search(int key) {
if(isEmpty()){
return -1;
}else{
for (int i = 0; i < this.usedsize; i++) {
if(this.elem[i] == key){
return i;
}
}
}
throw new UnsupportedOperationException("不合法數據");
}
//5..刪除
public boolean delete(int key) {
//查找是否有關鍵字key index 下標--》 找下標的方法 search()
int index = search(key);
//如果有:開始刪除 從找到的數組下標開始
if(index < 0){
return false;
}
for(int i = index; i < this.usedsize - 1; i++){
this.elem[i] = this.elem[i + 1];
}
usedsize--;
return true;
}
//6.得到pos位置的值 牽扯到 下標 在數組中,就要判斷是否小於最小下標或者,大於最大
public int getPos(int pos) {
if(pos < 0 || pos > this.usedsize || isEmpty()){
//return - 1; 可能數組中有- 1
throw new UnsupportedOperationException("pos的位置不合法異常");
}
return this.elem[pos];
}
//7.打印
public void show() {
for (int i = 0; i < this.usedsize; i++){
System.out.print(this.elem[i] + " ");
}
System.out.println();
}
}
public class SequenceListDemo {
public static void main(String[] args) {
TestSqlist testSqlist = new TestSqlist();
for (int i = 0; i < 10; i++){
testSqlist.insear(i, i);
}
testSqlist.show();
testSqlist.insear(10,2);
testSqlist.insear(3,5);
testSqlist.show();
System.out.println("---------------------");
System.out.println(testSqlist.search(6));
System.out.println("---------------------");
testSqlist.delete(4);
testSqlist.show();
System.out.println("---------------------");
System.out.println(testSqlist.getPos(6));
System.out.println("---------------------");
System.out.println(testSqlist.getPos(-1));
System.out.println("---------------------");
System.out.println(testSqlist.search(-3));
}
}
相關鏈接:
https://baike.sogou.com/v105830.htm?fromTitle=線性表
http://www.cnblogs.com/wincai/p/5893475.html
https://wenwen.sogou.com/z/q658164040.htm
2018.12.08/週六
by 922