1. 概念
線性結構的定義:
在數據元素的非空有限集中,存在唯一的一個被稱作“第一個”的數據元素;存在唯一的一個被稱作“最后一個”的數據元素;除第一個之外,集合中的每個數據元素均只有一個前驅;除最后一個之外,集合中每個數據元素均只有一個后繼。
線性結構包括線性表、堆棧、隊列、字符串、數組等等,其中最常用的是線性表。
線性表:
線性表是n個數據元素的有限序列,其元素可以是一個數、一個符號,也可以是多個數據項組成的復合形式,甚至可以是一頁書或其他更復雜的信息。
同一個線性表中的數據元素必須屬於同一種數據類型。
2. 基本操作
- 初始化——構造一個空的線性表
- 插入——在線性表的第 i 個位置之前插入一個新元素
- 刪除——刪除線性表中的第 i 個數據元素
- 查找——找出線性表中滿足特定條件的元素的位置
- 獲取——獲取線性表中的第 i 個數據元素
- 修改——修改線性表中第 i 個元素
- 判空——判斷當前線性表是否為空
- 求長度——求線性表中的數據元素的個數
- 正序遍歷——遍歷輸出線性表中的元素
- 銷毀——銷毀一個已經存在的線性表
3. 線性表的順序實現
圖:
代碼
// 線性表的順序實現
public class SequenceList<T> {
private int initLength = 10; // 數組初始化長度
private T[] arrList; // 使用數組來實現線性表
private int length; // 線性表長度
public SequenceList() {
this.arrList = (T[]) new Object[initLength];
length = 0;
}
public SequenceList(int len) {
if (len < 1) {
System.out.println("初始長度不合法!");
System.exit(1);
}
this.arrList = (T[]) new Object[len];
length = 0;
}
// 判空
public boolean isEmpty() {
return length == 0;
}
// 清空線性表
public void clear() {
length = 0;
arrList = null;
}
// 返回線性表長度
public int getSize() {
return length;
}
// 遍歷輸出
public void printArrList() {
for (int i = 0; i < length; i++) {
System.out.print(arrList[i] + "\t");
}
System.out.println();
}
// 在指定的位置插入元素
public boolean insert(T value, int pos) {
if (pos < 1 || pos > length + 1) {
System.out.println("pos值不合法,無法進行插入操作!");
return false;
}
if (length == arrList.length) {
T[] temp = (T[]) new Object[length * 2];
for (int i = 0; i < length; i++) {
temp[i] = arrList[i];
}
arrList = temp;
}
// 將元素向后移一位
for (int i = length; i >= pos; i++) {
arrList[i] = arrList[i - 1];
}
arrList[pos - 1] = value; // 插入值
length++;
return true;
}
// 刪除指定位置的元素
public T remove(int pos) {
if (isEmpty()) {
System.out.println("線性表為空,不能進行刪除操作!");
return null;
}
if (pos < 1 || pos > length) {
System.out.println("pos值不合法,不能進行刪除操作!");
return null;
}
T temp = arrList[pos - 1];
// 將第pos到length之間的元素前移一位
for (int i = pos; i < length; i++) {
arrList[i - 1] = arrList[i];
}
length--;
return temp;
}
// 修改指定位置的元素
public boolean modify(T value, int pos) {
if (isEmpty()) {
System.out.println("線性表為空,不能進行修改操作!");
return false;
}
if (pos < 1 || pos > length) {
System.out.println("pos值不合法,不能進行修改操作!");
return false;
}
arrList[pos - 1] = value;
return true;
}
// 查詢指定元素的位置
public int find(T value) {
if (isEmpty()) {
System.out.println("線性表為空,不能進行查詢操作!");
return -1;
}
for (int i = 0; i < length; i++) {
if (arrList[i].equals(value)) {
return i + 1;
}
}
return -1;
}
// 查詢指定位置的元素
public T value(int pos) {
if (isEmpty()) {
System.out.println("線性表為空,不能進行修改操作!");
return null;
}
if (pos < 1 || pos > length) {
System.out.println("pos值不合法,不能進行修改操作!");
return null;
}
return arrList[pos - 1];
}
}
// 測試
class Test {
public static void main(String[] args) {
SequenceList<Integer> sl = new SequenceList<>();
int[] arr = {12, 14, 16, 18, 20};
for (int i = 0; i < arr.length; i++) {
sl.insert(arr[i], i + 1); // 插入
}
sl.printArrList();
sl.remove(5); // 刪除第5個
System.out.println("刪除第5個:");
sl.printArrList();
sl.modify(1000, 3); // 修改第3個值為 1000
System.out.println("修改第3個值為 1000 :");
sl.printArrList();
System.out.println("查詢元素14在第幾個:" + sl.find(14)); // 查詢
System.out.println("線性表中第3個的值:" + sl.value(3));
System.out.println("線性表長度:" + sl.getSize());
sl.clear();
sl.printArrList();
}
}
4. 線性表的鏈式實現
單鏈表結構圖:
線性表的鏈式實現代碼:
// 節點
class Node<T> {
T data;
Node<T> next;
public Node(Node<T> next) {
this.next = next;
}
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
}
// 實現類
class LinkList<T> {
private Node<T> head; // 頭節點
private int length; // 線性表長度
public LinkList() {
length = 0;
head = new Node<>(null);
}
// 判空
public boolean isEmpty() {
return length == 0;
}
// 線性表長度
public int getSize() {
return length;
}
// 遍歷
public void printLinkList() {
Node<T> p = head.next;
while(p != null) {
System.out.print(p.data + "\t");
}
System.out.println();
}
// 銷毀
public void clear() {
length = 0;
head.next = null;
}
// 插入
public boolean insert(T value, int pos) {
if(pos < 1 || pos > length + 1) {
System.out.println("插入的位置不合法!");
return false;
}
int num = 1;
Node<T> p = head, q = head.next;
while(num < pos) {
p = q;
q = q.next;
num++;
}
p.next = new Node<>(value, q);
length++;
return true;
}
// 刪除
public T remove(int pos) {
if (isEmpty()) {
System.out.println("線性表為空,不能進行刪除操作!");
return null;
}
if (pos < 1 || pos > length) {
System.out.println("刪除的位置不合法!");
return null;
}
int num = 1;
Node<T> p = head, q = head.next;
while(num < pos) {
p = q;
q = q.next;
num++;
}
p.next = q.next;
length--;
return q.data;
}
// 修改
public boolean modify(T value, int pos) {
if (isEmpty()) {
System.out.println("線性表為空,不能進行修改操作!");
return false;
}
if (pos < 1 || pos > length) {
System.out.println("修改的位置不合法!");
return false;
}
int num = 1;
Node<T> p = head.next;
while(num < pos) {
p = p.next;
num++;
}
p.data = value;
return true;
}
// 查詢指定元素的位置
public int find(T value) {
int num = 1;
Node<T> p = head.next;
while (p != null) {
if (p.data.equals(value)) {
return num;
}
p = p.next;
num++;
}
return -1;
}
// 查詢指定位置的元素
public T getValue(int pos) {
if (isEmpty()) {
System.out.println("線性表為空!");
return null;
}
if (pos < 1 || pos > length) {
System.out.println("指定的位置不合法!");
return null;
}
int num = 1;
Node<T> p = head.next;
while (num < pos) {
p = p.next;
num++;
}
return p.data;
}
// 測試
public static void main(String[] args) {
LinkList<Integer> linkList = new LinkList<>();
int[] arr = {12, 14, 16, 18};
for (int i = 0; i < arr.length; i++) {
linkList.insert(arr[i], i + 1);
}
linkList.printLinkList();
linkList.modify(100, 2);
linkList.printLinkList();
linkList.remove(4);
linkList.printLinkList();
System.out.println(linkList.find(100));
System.out.println(linkList.length);
}
}