本篇用java實現數據結構的線性存儲
作爲我學java數據結構學習筆記
源碼分享在github:數據結構,當然你也可以從下面的代碼片中或我其他博文獲取
這是第一部分線性存儲,接下來我會陸續更新噠~
1.接口
package code.list;
public interface Ilist {
public void clear();//置空
public boolean isEmpty();//判空
public int length();
public Object get(int i) throws Exception;//返回線性表中第i個值
public void insert(int i,Object x) throws Exception;
public void remove(int i) throws Exception;
public void display();
}
2.順序表
package code.list;
/*
* 順序表
*
* */
public class SqList implements Ilist {
private Object []listElme; //線性表儲存空間
private int curLen; //線性表當前長度
//順序表類的構造函數,構造一個儲存空間容量爲maxSize的線性表
public SqList(int maxSize) {
curLen = 0; //設置順序表當前長度爲0
listElme = new Object[maxSize]; //爲順序表分配maxSize個春村單元
}
//將一個以及存在 的線性表重置爲空表
@Override
public void clear() {
curLen = 0;
}
//判斷線性表中的數據元素個數是否爲0,若爲0,則返回true;否則返回false
public boolean isEmpty() {
return curLen==0;
}
//求線性表中的數據元素個數並返回其值
public int length() {
return curLen;
}
//讀取到線性表中的第i個數據元素並由函數返回其值,其中i的取值範圍爲:0<=i<=length()-1,若i值不在此範圍則拋出異常
public Object get(int i) throws Exception{
if(i<0||i>curLen-1) //i小於0或者大一表長減一
throw new Exception("第"+i+"個元素不存在");//拋出異常
return listElme[i];//返回順序表中第i個數據元素
}
//在線性表的第i個數據元素之前插入一個值爲x的數據元素
public void insert(int i, Object x) throws Exception {
if(curLen==listElme.length)//判斷順序表是否已經滿
throw new Exception("順序表已滿");//拋出異常
if(i<0||i>curLen)//i不合法
throw new Exception("插入位置不合法");//拋出異常
for(int j = curLen;j > i;j --){
listElme[j] = listElme[j-1];
}//插入位置及其以後的所有數據元素後移一位
listElme[i] = x;//插入x
curLen++;//表長加1
}
//刪除並返回線性表中 第i個元素
public void remove(int i) throws Exception{
if(i<0||i>curLen-1){//i不合法
throw new Exception("刪除位置不合法");//拋出異常
}
for(int j = i;j<curLen-1;j++){
listElme[j] = listElme[j+1];//被刪除元素之後的所有數據左移一個存儲位置
}
curLen--;//表長減一
}
//返回線性表中首次出現制定的數據元素的位序號,若線性表中不包含次數據元素,則返回-1
public int indexOf(Object x) {
int j = 0;//j指示順序表中待比較的數據元素,起初值指示順序表中第0個元素
while(j<curLen&&!listElme[j].equals(x))//依次比較,如果j<curLen並且此項不等於x
j++;
if(j<curLen)//判斷j的位置是否位於順序表中
return j;
else {
return -1;//值爲x的數據元素再順序表中不存在
}
}
//輸出線性表中的數據元素
public void display() {
for(int j = 0;j<curLen;j++)
System.out.print(listElme[j]+"");
System.out.println();
}
}
3.鏈表
鏈表節點類
package code.list;
public class Node {
public Object data;//存放節點值
public Node next;//後繼節點的引用
//無參數時的構造函數
public Node(){
this(null,null);
}
//帶一個參數時的構造函數
public Node(Object data){
this(data,null);
}
//帶兩個參數的構造函數
public Node(Object data, Node next){
this.data = data;
this.next = next;
}
}
鏈表實現:
package code.list;
/*
* 鏈表
*
* */
import java.util.Scanner;
public class LinkList implements Ilist {
public Node head;//單鏈表的頭指針
//單鏈表的構造函數
public LinkList(){
head = new Node();//初始化頭節點
}
//構造一個長度爲n的單鏈表
public LinkList(int n,boolean Order) throws Exception{
this();//初始化頭節點
if(Order){//用尾插法順序建立單鏈表
create1(n);
}else {//用頭插法逆序建立單鏈表
create2(n);
}
}
//用尾插法順序建立單鏈表,其中n爲單鏈表的結點個數
public void create1(int n) throws Exception{
Scanner sc = new Scanner(System.in);//構造用於輸入的對象
for(int j = 0;j<n;j++){//輸入n個結點的數據域值
insert(length(), sc.next());//生成新結點,插入到表尾
}
}
//用頭插法逆序建立單鏈表,其中n爲單鏈表的節點個數
public void create2(int n) throws Exception{
Scanner sc = new Scanner(System.in);//構造用於輸入的對象
for(int j = 0;j<n;j++){//輸入n個結點的數據域值
insert(0, sc.next());//生成新結點,插入到表尾
}
}
//將一個以及存在 的帶頭節點單鏈表重置爲空表
public void clear() {
head.data = null;
head.next = null;
}
//判斷帶頭節點的單鏈表是否爲空
public boolean isEmpty() {
return head.next ==null;//頭結點後面是首節點
}
//求帶頭節點的單鏈表的長度
public int length() {
Node p = head.next;//初始化,p指向首節點,length爲計數器
int length = 0;
while(p!=null){//從首節點開始向後查找,直到p爲空
p = p.next;//指向後繼節點
++length;//長度增1
}
return length;
}
//讀取到帶頭節點的單鏈表中的第i個節點(這裏的第i個指的是從0開始計數)
public Object get(int i) throws Exception {
Node p = head.next;//初始化,p指向首節點,j爲計數器
int j = 0;
while(p!=null&&j<i){//從首節點開始向後查找,直到p指向第i個結點或p爲空
p = p.next;//指向後繼結點
++j;//計數器的值增1
}
if(j > i||p==null){
throw new Exception("第"+i+"個元素不存在");
}
return p.data;
}
//在第i個節點前插入一個值爲x的新節點
public void insert(int i, Object x) throws Exception {
Node p = head;//初始化p爲頭節點,j爲計數器
int j = -1;
while(p!=null&&j<i-1){//尋找第i個結點的前驅
p = p.next;
++j;
}
if(j>i-1||p==null){ //第一個條件若爲真,則說明參數i的值小於0,若第二個條件爲真,則說明參數i的值大於表長
throw new Exception("插入位置不合法");
}
Node s = new Node(x);//生成新結點
s.next = p.next;//修改連,使新結點插入單鏈表中
p.next = s;
}
//刪除第i個節點
public void remove(int i) throws Exception {
Node p = head;//初始化p指向頭節點,j爲計數器
int j = -1;
while(p.next!=null&&j<i-1){//尋找第i個結點的前驅
p = p.next;
++j;
}
if(j>i-1||p.next == null){
throw new Exception("刪除位置不合法");
}
p.next = p.next.next;//修改鏈指針,使待刪除結點從單鏈表中從單鏈表中脫離出來
}
//查找值爲x的節點
public int indexOf(Object x) {
Node p = head.next;//初始化,p指向首結點,j爲計數器
int j = 0;//下面從單鏈表中 的首結點你開始查找,直到p.data爲x或到達單鏈表的表尾
while(p!=null&&!p.data.equals(x)){
p = p.next;//指向下一個結點
++j;
}
if(p!=null){
return j;
}else{
return -1;
}
}
//輸出所有節點
public void display() {
Node node = head.next;//取出帶頭節點的單鏈表中的首節點
while(node!=null){
System.out.print(node.data +" ");//輸出節點的值
node = node.next;//取下一個節點
}
System.out.println();//換行
}
}
4.雙循環鏈表
雙循環鏈表節點類
package code.list;
/*
* 雙向鏈表的節點類
* */
public class DuLNode {
public Object data; //數據域
public DuLNode prior; //存放指向前驅結點的指針域
public DuLNode next; //存放指向後繼結點的指針域
public DuLNode(){ }
public DuLNode(Object data){
this.data = data;
this.prior = null;
this.next = null;
}
}
雙循環鏈表實現類:
package code.list;
import java.util.Scanner;
/*
* 雙向循環鏈表
*
* */
public class DuLinkList implements Ilist{
public DuLNode head; //雙向循環鏈表的頭結點
//雙向循環鏈表的構造函數,構造只含有一個頭節點的雙向循環鏈表
public DuLinkList(){
head = new DuLNode();
head.prior = head;
head.next = head;
}
//從表尾到表頭逆向創建雙向循環鏈表的算法,其中n爲該雙向循環鏈表的節點個數
public DuLinkList(int n) throws Exception{
this();
Scanner sc = new Scanner(System.in);
for (int j = 0;j < n;j++ ){
insert(0,sc.next());//生成新的節點插入到表頭
}
}
@Override
public void clear() {
this.head.next = null;
this.head.prior = null;
this.head.data = null;
}
@Override
public boolean isEmpty() {
return head.next ==null && head.prior == null;
}
@Override
public int length() {
DuLNode p = head.next;
int length = 0;
while (p != head){
p = p.next;
length++;
}
return length;
}
@Override
public Object get(int i) throws Exception {
DuLNode p = head.next;//初始化,p指向首節點,j爲計數器
int j = 0;
while(p!=head&&j<i){//從首節點開始向後查找,直到p指向第i個結點或p爲head
p = p.next;//指向後繼結點
++j;//計數器的值增1
}
if(j > i||p==head){
throw new Exception("第"+i+"個元素不存在");
}
return p.data;
}
//在帶頭節點的雙向循環鏈表中的插入操作
@Override
public void insert(int i, Object x) throws Exception {
DuLNode p = head.next;
int j = 0;
while (!p.equals(head) && j < i){//尋找到插入位置i
p = p.next;
++j;
}
if (j != i && !p.equals(head)) //i不合法
throw new Exception("插入位置不合法");
DuLNode s = new DuLNode(x);//生成新節點s
p.prior.next = s;
s.prior = p.prior;
s.next = p;
p.prior = s;
}
//帶頭結點的雙向循環鏈表中的刪除操作
@Override
public void remove(int i) throws Exception {
DuLNode p = head.next;
int j = 0;
while (!p.equals(head) && j <i){
p = p.next;
++j;
}
if (j != i){
throw new Exception("刪除位置不合理");
}
p.prior.next = p.next;
p.next.prior = p.prior;
}
@Override
public void display() {
DuLNode node = head.next;
while (!node.equals((head))){
System.out.println(node.data+" ");
node = node.next;
}
System.out.println();
}
}