線性表是最簡單和最經常使用的一種數據結構,它是有n個數據元素(節點)組成的有限序列。其中,數據元素的個數n爲表的長度,當n爲零時成爲空表,非空的線性表一般記爲:node
(a1,a2,… ,ai-1,ai, ai+1,…,an)
線性表的順序存儲指的是將線性表的數據元素按其邏輯次序依次存入一組地址連續的存儲單元裏,用這種方法存儲的線性表稱爲順序表。算法
public class SeqList { /* 初始空間爲10 */ private static final int LIST_SIZE = 10; /* 數組data用來存放元素 */ private int[] data; /* 當前表長,實際存儲元素的個數 */ private int length; }
順序表的插入運算是指在線性表的第i-1個元素和第i個元素之間插入一個新元素。因爲順序表邏輯上相鄰的元素在物理結構上也相鄰,其物理存儲關係也要發生相應的變化。除非i=n+1,不然必須將原順序表的第i個元素開始的全部元素分別向後移動1個位置。數組
/** * 在順序表list中第i個位置以前插入一個新元素node * @param list 順序表 * @param i 插入位置 * @param node 新元素 */ public void insertList(SeqList list, int i, int node) { if (i < 1 || i > list.length + 1) { System.out.println("position error"); return; } if (list.length >= LIST_SIZE) { System.out.println("overflow"); return; } for (int j = list.length - 1; j >= i - 1; j --) { /* 從最後一個元素開始逐一後移 */ list.data[j+1] = list.data[j]; } /* 插入新元素 */ list.data[i-1] = node; /* 表長加1 */ list.length ++; }
順序表的刪除運算指的是將表中第i個元素刪除,與插入運算相反,插入是向後移動元素,刪除運算則是向前移動元素。數據結構
/** * 在順序表list中刪除第i個元素,並返回被刪除的元素 * @param list 順序表 * @param i 元素位置 * @return node */ public int deleteList(SeqList list, int i) { int node = 0; if (i < 0 || i > list.length) { System.out.println("position error"); return node; } node = list.data[i-1]; for (int j = i; j < list.length; j ++) { /* 元素前移 */ list.data[j-1] = list.data[j]; } list.length --; return node; }
先以表長的一半爲循環控制次數,將表中最後一個元素同順序順數第一個元素交換,將倒數第二個元素同順數第二個元素交換,以此類推,直至交換完爲止。code
/** * 順序表逆置 * @param list 原始順序表 * @return 逆置後的順序表 */ public SeqList converts(SeqList list) { int node; int length = list.length/2; for (int i = 0; i < length; i ++) { /* 對稱交換元素 */ int j = list.length - 1 - i; node = list.data[i]; list.data[i] = list.data[j]; list.data[j] = node; } return list; }
鏈式存儲結構存儲線性表數據元素的存儲空間多是連續的,也多是不連續的,於是鏈表的節點是不能夠隨機存取的,鏈式存粗是最多見的存儲方式之一。it
在使用鏈式存儲結構表示每一個數據元素時,除了存儲元素自己的信息外,還須要一個存儲指示後繼元素存儲位置的地址,利用這種存儲方式表示的線性表稱爲鏈表。io
public class LinkList { /* 數據域 */ private char data; /* 後繼元素 */ private LinkList next; }
頭插法是從一個空表開始,重複讀入數據,生成新節點,將讀入的數據存放到新節點的數據域中,而後將新節點插入到當前鏈表的表頭上,直到結束爲止。class
/** * 頭插法建立表 * @param chars 字符數組 * @return 單鏈表 */ public LinkList createListF(char[] chars) { LinkList node; LinkList head = null; for (char ch : chars) { /* 申請新節點 */ node = new LinkList(); node.data = ch; /* 指向後繼節點 */ node.next = head; head = node; } /* 返回頭節點 */ return head; }
頭插法建表中節點的次序和輸入時的順序相反,若須要和輸入次序一致,則可以使用尾插法。List
/** * 尾插法建表 * @param chars 字符數組 * @return 單鏈表 */ public LinkList createListR(char[] chars) { LinkList node; LinkList head = null; LinkList rear = null; for (char ch : chars) { node = new LinkList(); node.data = ch; if (head == null) { /* 新節點爲頭節點 */ head = node; } else { /* 上一個節點指向新節點 */ rear.next = node; } /* 表尾指向新的節點 */ rear = node; } /* 返回頭節點 */ return head; }