这一篇开始我就讲java数据结构链表相关,在这上两个链表相关的demo(线性表(顺序结构)和链表(离散结构))
线性表
主要包括两个方面:既数据集和该数据集上的操作集合(功能接口)。
一、实现操作功能类
操作集合包括如下:
1.求元素个数
2.插入
3.删除
4.查找
5.判断是否为空
综上所述写个功能接口List_,该功能接口在链式表那里还要用到
public interface List_ {
int size();
boolean isEmpty();
void insert(int index,Object object)throws Exception;
void delete(int index)throws Exception;
Object get(int index)throws Exception;
}
接着实现线性表逻辑,功能逻辑类SequenceList_ 和 测试类Test
为了方便我在code里面添加注释,我就不在文章添加太多文字了
/**
* 顺序表
*
* @author robert
*
*/
public class SequenceList_ implements List_ {
private static final int DEFAULT_SIZE = 10;//表默认长度
public int mSize;//当前长度
private int mMaxSize;//最大长度
private Object[] mArraylists;//数组
public SequenceList_() {
init(DEFAULT_SIZE);//new 该对象的时候不赋值,默认长度
}
public SequenceList_(int size) {
init(size);//new 该对象的时候手动赋值长度
}
//初始化顺序表(数组)
public void init(int size) {
this.mMaxSize = size;
this.mSize = 0;
mArraylists = new Object[size];
}
@Override
public int size() {
return mSize;//返回长度
}
@Override
public boolean isEmpty() {
return mSize == 0;//判断是否为空
}
@Override
public void insert(int index, Object object) throws Exception {
if (index < 0 || index > mSize) {
throw new Exception("越界");
}
if (mSize == mMaxSize) {
throw new Exception("顺序表已满");
}
//反向遍历至插入位置,元素全部前移
for (int i = mSize; i > index; i--) {
mArraylists[i] = mArraylists[i + 1];
}
mArraylists[index] = object;
mSize++;
}
@Override
public void delete(int index) throws Exception {
if(isEmpty()){
throw new Exception("顺序表为空");//判断是否为空
}
if(index<0||index>mSize){
throw new Exception("越界");
}
//正向遍历至删除元素指针处
for (int i = index; i < mSize - 1; i++) {
mArraylists[index] = mArraylists[index - 1];
}
mSize--;
}
//该处是获取具体指针的指向位置的值
@Override
public Object get(int index) throws Exception {
if (index < 0 || index > mSize - 1) {
throw new Exception("越界");
}
return mArraylists[index];
}
}
最后是Test_
public class Test_list {
public static void main(String[] args) {
SequenceList_ list_ = new SequenceList_(5);
try {
list_.insert(list_.mSize, new Student("asd11", "tom11", "1231", "12233234456"));
list_.insert(list_.mSize, new Student("asd12", "tom12", "1232", "12233234456"));
list_.insert(list_.mSize, new Student("asd13", "tom13", "1233", "12233234456"));
list_.insert(list_.mSize, new Student("asd14", "tom14", "1234", "12233234456"));
list_.insert(list_.mSize, new Student("asd15", "tom14", "1234", "12233234456"));
for (int i = 0; i < list_.size(); i++) {
System.out.println(list_.get(i));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
补上bean类,即上面提到的数据集
public class Student {
private String nicename;
private String username;
private String password;
private String telephone;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String nicename, String username, String password, String telephone) {
super();
this.nicename = nicename;
this.username = username;
this.password = password;
this.telephone = telephone;
}
public String getNicename() {
return nicename;
}
public void setNicename(String nicename) {
this.nicename = nicename;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
@Override
public String toString() {
return "Student [nicename=" + nicename + ", username=" + username + ", password=" + password + ", telephone="
+ telephone + "]";
}
}
输出结果:
链表
然后是离散类型的表,即链表
单链表是由一个一个结点组成的,因此,要设计单链表类,必须先设计结点类。结点类的成员变量有两个:一个是数据元素,另一个是表示下一个结点的对象引用(即指针)。
设计操作:
1.头结点的初始化
2.非头结点的构造
3.获取该结点指向的下个结点
4.设置该结点指向的下个结点
5.设置该结点的数据
6.获取该结点的数据
这里同样使用上面定义的List_接口功能类,此处就不贴了
抽象数据类型结点类
/**
* 节点类
*
* @author robert
*
*/
public class ListNode_ {
public Object elenment;//数据域
public ListNode_ next;//指针域
public ListNode_(ListNode_ next) {
super();
this.next = next;
}
public ListNode_(Object elenment, ListNode_ next) {
super();
this.elenment = elenment;
this.next = next;
}
public Object getElenment() {
return elenment;
}
public void setElenment(Object elenment) {
this.elenment = elenment;
}
public ListNode_ getNext() {
return next;
}
public void setNext(ListNode_ next) {
this.next = next;
}
@Override
public String toString() {
return "ListNode_ [elenment=" + elenment + ", next=" + next + "]";
}
}
处理逻辑类的部分
public class LinkedList_ implements List_ {
ListNode_ mConnert;//当前节点对象
ListNode_ mHead;//头结点对象
public int mSize;
public LinkedList_() {
this.mConnert = this.mHead = new ListNode_(null);
this.mSize = 0;
}
//操作指针的方法
private void index(int index) throws Exception {
if (index < -1 || index > mSize - 1) {
throw new Exception("越界");
}
if (index == -1) {
return;
}
this.mConnert = mHead.next;
int count = 0;
while (index>count&&mConnert != null) {
this.mConnert = this.mConnert.next;
count++;
}
}
@Override
public int size() {
return mSize;
}
@Override
public boolean isEmpty() {
return mSize == 0;
}
@Override
public void insert(int index, Object object) throws Exception {
if(index<0||index>mSize){
throw new Exception("越界");
}
index(index-1);//操作指针
mConnert.setNext(new ListNode_(object, mConnert.next));//添加数据
mSize++;//长度增加
}
@Override
public void delete(int index) throws Exception {
// TODO Auto-generated method stub
if(index<0||index>mSize){
throw new Exception("越界");
}
if(isEmpty()){
throw new Exception("为空");
}
index(index-1);
mConnert.setNext(mConnert.next.next);
mSize--;
}
@Override
public Object get(int index) throws Exception {
if (index < -1 || index > mSize - 1) {
throw new Exception("越界");
}
index(index);
return mConnert.getElenment();
}
}
测试类Test
public class Test_Link {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
LinkedList_ list = new LinkedList_();
for (int i = 0; i < 10; i++) {
int temp = ((int) (Math.random() * 100)) % 100;
list.insert(i, temp);
System.out.print(temp + " ");
}
list.delete(6);
System.out.println("\n------删除第五个元素之后-------");
for (int i = 0; i < list.mSize; i++) {
System.out.print(list.get(i) + " ");
}
}
}
结果
单向循环列表
单向循环链表和单链表类各部分都相似,不同的是,最后一个结点的指针域不指向null,而是指向head头结点,和上述一样,99%的地方都不用改,只需改动两处即可
在功能逻辑类里面改动构造方法和index方法
public LinkList_() {
this.head = corrend = new ListNode_(null);
this.size = 0;
this.head.next = head;//1
}
public void index(int index) throws Exception {
if (index < -1 || index > size - 1) {
throw new Exception("参数错误");
}
if (index == -1) {
return;
}
corrend = this.head.next;
int j = 0;
while (j < index && corrend != head) {//2,null改为head
corrend = this.corrend.next;
j++;
}
}
双向循环链表
双向链表是每个结点除后继指针外还有一个前驱指针。
实现方式和单链表略有不同
接口功能类一样使用List_
抽象数据类型结点类
public class DoubleNode_ {
public Object elenment;
public DoubleNode_ tail;
public DoubleNode_ next;
public DoubleNode_(DoubleNode_ next) {
this.next = next;
}
public DoubleNode_(Object elenment, DoubleNode_ next) {
this.elenment = elenment;
this.next = next;
}
public Object getElenment() {
return this.elenment;
}
public void setElenment(Object elenment) {
this.elenment = elenment;
}
public DoubleNode_ getTail() {
return this.tail;
}
public void setTail(DoubleNode_ tail) {
this.tail = tail;
}
public DoubleNode_ getNext() {
return this.next;
}
public void setNext(DoubleNode_ next) {
this.next = next;
}
}
功能逻辑实现
/**
* 双向循环链表
*
* @author robert
*
*/
public class CycleLinkList_ implements List_ {
DoubleNode_ head;
DoubleNode_ corrend;
public int size;
public CycleLinkList_() {
this.head = corrend = new DoubleNode_(null);
this.size = 0;
this.head.next = head;
this.head.tail = head;
}
public void index(int index) throws Exception {
if (index < -1 || index > size - 1) {
throw new Exception("参数错误");
}
if (index == -1) {
return;
}
corrend = this.head.next;
int j = 0;
while (j < index && corrend != head) {
corrend = this.corrend.next;
j++;
}
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public Object get(int index) throws Exception {
if (index < -1 || index > size - 1) {
throw new Exception("参数错误");
}
index(index);
return corrend.getElenment();
}
@Override
public void insert(int index, Object object) throws Exception {
if(index<0||index>size){
throw new Exception("参数错误");
}
index(index-1);
corrend.setNext(new DoubleNode_(object, corrend.next));
corrend.next.setTail(corrend);
corrend.next.next.setTail(corrend.next);
size++;
}
@Override
public void delete(int index) throws Exception {
if(index<0||index>size){
throw new Exception("参数错误");
}
if(isEmpty()){
throw new Exception("链表为空");
}
index(index-1);
corrend.setNext(corrend.next.next);
corrend.setTail(corrend);
size--;
}
}
测试类Test
public class Test_Double {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
CycleLinkList_ list = new CycleLinkList_();
for (int i = 0; i < 10; i++) {
int temp = ((int) (Math.random() * 100)) % 100;
list.insert(i, temp);
System.out.print(temp + " ");
}
list.delete(3);
System.out.println("\n------删除第三个元素之后-------");
for (int i = 0; i < list.size; i++) {
System.out.print(list.get(i) + " ");
}
}
}
结果:
下篇开始讲java数据结构堆栈相关