所有的数据结构都可以大致分为两类,由连续单位构成或者由离散单位构成,具体到实体也就是数组实现或者链表实现。数组实现的数据结构方便查找和修改但不方便增删,链表实现的数据结构则刚好相反,适于增删却不便于查找。
今天我们用链表来实现队列。
我们需要实现的功能无非增删查改,这也是一般的数据结构都会具备的功能。
一、关于Myqueue
我们为这个队列设置一个Node类型的头结点head,这个头结点并不放数据,仅仅存一个指针,这样会更便于后面的插入和删除操作。然后再定义一个Node型的结点cur来表示当前结点,以及定义一个int 型的size记录队列的长度。
二、关于Node
我想实现的只是一个简单的单向队列,所以仅仅包含数据域data和指向下一个结点的“指针”next(Java中没有指针,只是类似一个索引),并且定义一个构造方法。(如果想实现双向队列可以定义front,next两个指针)代码如下:
public class Myqueque {
public Node head; //头结点,不存数据
public Node cur; //当前节点
public int size; //队列长度
public class Node {
public Object data;
public Node next;
public Node(Object data) {
this.data = data;
}
}
三
、增删查改
增 :增添操作给的参数是新加入的数据
1.我们先创建一个新的节点来接受数据。
2. 然后按照表是否为空表分讨论,因为两种情况的head指针位置是不同的。若为空表,则把新节点当作表头即可,让head 和cur都指向它;若不是空表,创建节点后让cur指向它。
代码如下:
// 增
public void Add(Object input) {
Node addnode = new Node(input);
if(head==null) { //如果头结点不存在
head=addnode;
head.next=null;
cur=head;//移动当前节点到头节点
}
else {
//头节点存在,移动当前节点的位置
cur.next=addnode;
cur=cur.next;
}
size++; //数组的大小++
}
删:删除操作给的参数是希望删除的位置。
删除前也要问自己一个问题:表是不是空的?如果空了删个鬼哦;
如果删的是表头,移动头指针就好了;
如果删的是中间,则需要改变一下中间被删除节点的前一个节点,让其next绕过希望删除的节点temp;如果是删除表尾,则直接让cur.next=null。但是其实这两种情况可以合并为temp.next=temp.next.next;
// 删
public void Delete(int index) {
// Object retuNode; 如果希望取得想删除节点的值就创一个节点接收数据,最后返回。此处我不想返回它的值,可以自己灵活更改
if (size <= 0) //数组的size必须大于0
System.out.println("Error.");
else {
if(index==0){ //删头节点
// retuNode=head.data;
head=head.next; //关键句
}
else if (index > 0 && index <= size) { //删除中间或表尾
int count = 0;
Node temp=head;
while (count != index) {
temp=temp.next;
count++;
}
retuNode=temp.next.data;
temp.next=temp.next.next; //关键句
size--;
}
else { //输入越界
System.out.println("No such node.");
}
}
}
查:查找操作给的参数是被查找元素的位置index
同样的,要考虑给的index是否合理,有没有越界;接下来定义一个节点temp接收数据,操作很简单了,不解释了
//查
public Object Search(int index) {
int count = 0;
Node temp=head;
if (index >= 0 && index < this.Size()) {
while (count<index) {
temp = temp.next;
count++;
}
return temp.data;
} else { //如果要找的index越界
System.out.println("No such node.");
return null;
}
}
改:修改与查找十分相似,区别仅仅是参数除了修改的位置还多了个数据N,因为不知道N是什么类型的所以用Object;
步骤就是先查找,再赋值。
// 改
public void Change(int index,Object N) {
int count = 1;
Node temp=head;
if (index >= 0 && index <= this.Size()) {
while (count != index) {
temp = temp.next;
count++;
}
temp.data=N;
// System.out.println(temp.data+"hhhhhhhhh已修改"); //调试用的
} else {
System.out.println("No such node.");
}
}
好了现在队列创建好了,我们给它添加一个测试类看看对不对:
public class Test {
public int number;
public String name;
public Test(int num,String s){
number=num;
name=s;
}
/*public String toString() {
return getClass().getName() +;
}*/
public static void main(String[] args) {
Test t1=new Test(1,"hhhhh");
Test t2=new Test(2,"xxxxx");
Test t3=new Test(3,"eeeee");
Test t4=new Test(4,"aaaaa");
Myqueque q=new Myqueque();
q.Add(t1);
q.Add(t2);
q.Add(t3);
q.Add(t4);
Test test1=(Test)q.Search(0);
// Test test2=(Test)q.Change(3,"这是被修改的");
System.out.println("sssssssssss+"+test1.number+":"+test1.name);
//System.out.println("333333333333333+"+test2.number+":"+test2.name);
q.Change(3,"这是被修改的");
q.Delete(0);
Test ts4=(Test)q.Search(0);
System.out.println("shanchu"+ts4.number+":"+ts4.name);
q.Change(3, "hahahhah");
}
}
测试的结果我就不放截图了(哈哈哈。。。)你可以自己试试哦