目录
一.链结点
二.单链表
1.单链表的插入方法insertFirst()
2.单链表的删除方法deleteFirst()
3.链表显示displayList()
4.单链表代码:
三. 查找和删除指定链结点
四.双端链表
五.用链表实现的栈
六.用链表实现队列
七.有序链表
八.双向链表
1.遍历
2.插入
3.删除
一.链结点
在链表中,每一个数据项都包含在链结点中,一个链结点是某个类的对象,这个类叫Link,因为一个类有许多类似的结点,所有有必要用一个不同于链表的类来表达链结点,每个Link对象都包含一个对下一个链结点引用的字段next,但是链表本身的对象中一个字段指向对第一个链结点的引用
链结点 Link的定义:
class Link{
public int iData;
public double dData;
public Link next;
}
二.单链表
单链表的操作:
·在链表头插入一个数据项
·在链表头删除一个数据项
·遍历链表显示它的内容
1.单链表的插入方法insertFirst()
链表插入:
定义一个新的链表结点,让新结点连接旧结点,再让头结点连接新结点
插入insertFirst()代码:
public void insertFirst(int id,double dd){
Link newLink=new Link(id,dd);
newLink.next=first;
first=newLink;
}
2.单链表的删除方法deleteFirst()
链表删除:
通过把first重新指向第二个链结点,断开和第一个链结点的连接
deleteFirst():
public Link deleteFirst(){
Link temp=first;
first=first.next;
return temp;
}
3.链表显示displayList()
代码:
public void displayList(){
System.out.print("List(fist—>last):");
Link current=first;
while(current!=null){
current.displayLink();
current=current.next;
}
System.out.print("");
}
4.单链表代码:
class Link{ //定义链表
public int iData;
public double dData;
public Link next;
public void displayLink(){
System.out.print("{"+iData+","+dData+"}");
}
public Link(int id,double dd){
iData=id;
dData=dd;
}
}
class LinkList{ //定义单链表
private Link first;
public LinkList(){
first=null;
}
public boolean isEmpty(){ //链表是否为空
return (first==null);
}
public void insertFirst(int id,double dd){ //单链表插入操作
Link newLink=new Link(id,dd);
newLink.next=first;
first=newLink;
}
public Link delectFirst(){ //删除操作
Link temp=first;
first=first.next;
return temp;
}
public void displayList(){ //显示单链表
System.out.println("List(first—>last):");
Link current=first;
while (current!=null){
current.displayLink();
current=current.next;
System.out.println(" ");
}
}
}
三. 查找和删除指定链结点
查找的实现:通过一个current变量开始时指向first,然后通过不断地把自己赋值为current.next,沿着链表向前移动,如果要查找的值和链表的值相同,就返回链表结点的引用,如果没有找到就返回null
删除操作的实现:删除操作先寻找到要删除的结点,然后将前一个结点和后一个结点连接,实现删除操作
代码:
public class CollectionDemo {
public static void main(String[] args) {
LinkList linkList = new LinkList();
linkList.insertFirst(1,12);
linkList.insertFirst(2,23);
linkList.insertFirst(3,34);
linkList.displayList();
Link j=linkList.find(2);
System.out.println("第二个元素为:"+j.dData);
Link d=linkList.delect(1);
System.out.println("删除第一个元素后:");
linkList.displayList();
}
}
class Link { //链表结点
public int iData;
public double dData;
public Link next; //链表结点初始化
public Link(int id, double dd) {
this.dData = dd;
this.iData = id;
}
//显示数据
public void displayLink() {
System.out.print("{" + iData + "," + dData + "}");
}
}
//链表定义
class LinkList{
private Link first;
public LinkList(){
first=null;
}
//插入操作
public void insertFirst(int id,double dd){
Link newLink=new Link(id,dd);
newLink.next=first;
first=newLink;
}
//查找操作
public Link find(int key){
Link current=first;
while(current.iData!=key){
if (current.next==null)
return null;
else current=current.next;
}
return current; //返回查找的链结点引用
}
//删除操作
public Link delect(int key){
Link current=first; //查询结点
Link previous=first; //前置结点
while (current.iData!=key){
//如果没有找到指定结点
if (current.next==null)
return null;
else {
previous=current; //设置前置结点
current=current.next; //继续查询
}
}
//找到指定结点
if (current==first)//指定结点为头结点
first=first.next;
else
previous.next=current.next;
return current;
}
//显示列表
public void displayList(){
System.out.println("List(first-->last):");
Link current=first;
while (current!=null){
current.displayLink();
System.out.print(" ");
current=current.next;
}
System.out.println(" ");
}
}
效果:
四.双端链表
双端链表与传统链表相似,但它多了一个特性,就是对最后一个结点的引用可以像在链表头结点一样,在链表尾插入一个链结点
双端链表的插入操作:
双端链表代码:
public class CollectionDemo {
public static void main(String[] args) {
FirstLastList firstLastList=new FirstLastList();
firstLastList.insertFirst(1);
firstLastList.insertFirst(2);
firstLastList.insertFirst(3);
firstLastList.insertLast(4); //末尾插入
firstLastList.displayList();
//输出:List(first-->last):
//3 2 1 4
}
}
class Link{ //链表结点
public long dData;
public Link next;
public Link(long d){
dData=d;
}
public void displayLink(){
System.out.print(dData+" ");
}
}
class FirstLastList{
private Link first;
private Link last;
public FirstLastList(){
first=null;
last=null;
}
public boolean isEmpty(){ //判断是否为空
return first==null;
}
public void insertFirst(long dd){ //表头插入
Link newLink=new Link(dd);
if(isEmpty()) //如果表头为空,连接last
last=newLink;
//如果表头不为空
newLink.next=first;
first=newLink;
}
public void insertLast(long dd){ //表尾插入
Link newLink=new Link(dd);
if (isEmpty()) //如果表头为空,
first=newLink;
else //如果表头不为空
last.next=newLink;
last=newLink;
}
public long deleteFirst(){ //删除元素
long temp=first.dData;
if (first.next==null)
last=null;
first=first.next;
return temp;
}
public void displayList(){ //输出链表
System.out.println("List(first-->last):");
Link current=first;
while(current!=null){
current.displayLink();
current=current.next;
}
System.out.println(" ");
}
}
五.用链表实现的栈
栈相关内容可以学习:数据结构与算法java实战篇--队列和栈
代码实现:
public class CollectionDemo {
public static void main(String[] args) {
LinkStack linkStack=new LinkStack();
linkStack.push(1);
linkStack.push(2);
linkStack.push(3);
linkStack.push(4);
linkStack.displayStack();
linkStack.pop(); //先进后出,'4'出栈
linkStack.displayStack();
}
}
class Link{
public long dData;
public Link next;
public Link(long dd){
dData=dd;
}
public void displayLink(){ //显示结点
System.out.print(dData+" ");
}
}
//定义链表
class LinkList{
private Link first;
public LinkList(){ //链表初始化
first=null;
}
public boolean isEmpty(){ //判断是否为空
return (first==null);
}
public void insertFirst(long dd){ //插入操作
Link newLink=new Link(dd);
newLink.next=first;
first=newLink;
}
public long deleteFirst(){ //删除操作
Link temp=first;
first=first.next;
return temp.dData;
}
public void displayList(){
Link current =first;
while(current!=null){
current.displayLink();
current=current.next;
}
System.out.println(" ");
}
}
//链表实现
class LinkStack{
private LinkList theList;
public LinkStack(){
theList=new LinkList();
}
public void push(long i){ //入栈操作
theList.insertFirst(i);
}
public long pop(){ //出栈操作
return theList.deleteFirst();
}
public boolean isEmpty(){ //判断栈是否为空
return (theList.isEmpty());
}
public void displayStack(){
System.out.print("Stack(top-->bottom):");
theList.displayList();
}
}
效果:
六.用链表实现队列
代码:
public class CollectionDemo {
public static void main(String[] args) {
LinkQueue linkQueue=new LinkQueue();
linkQueue.insert(1);
linkQueue.insert(2);
linkQueue.insert(3);
linkQueue.insert(4);
linkQueue.insert(5);
linkQueue.displayQueue();
linkQueue.remove(); //队列先进先出
linkQueue.displayQueue();
}
}
class Link{
public long dData;
public Link next;
public Link(long dd){
dData=dd;
}
public void displayLink(){ //显示结点
System.out.print(dData+" ");
}
}
//定义链表
class FirstLastList{
private Link first;
private Link last;
public FirstLastList(){
first=null;
last=null;
}
public boolean isEmpty(){
return (first==null);
}
public void insertLast(long dd){ //队列头出尾进
Link newLink=new Link(dd);
if(isEmpty())
first=newLink;
else
last.next=newLink;
last=newLink;
}
public long deleteFrist(){ //队列头删除
long tamp= first.dData;
if(first.next==null)
last=null;
first=first.next;
return tamp;
}
public void displayList(){ //输出元素
Link current=first;
while(current!=null){
current.displayLink();
current=current.next;
}
System.out.println(" ");
}
}
//链表实现队列
class LinkQueue{
private FirstLastList theList;
public LinkQueue(){
theList=new FirstLastList();
}
public boolean isEmpty(){ //判断是否为空
return theList.isEmpty();
}
public void insert(long i){ //入队操作
theList.insertLast(i);
}
public long remove(){ //出队操作
return theList.deleteFrist();
}
public void displayQueue(){ //显示队列
System.out.println("Queue(first-->last):");
theList.displayList();
}
}
效果:
七.有序链表
有序链表在插入数据时,链表会先查找插入数据一个插入的位置,再进行插入操作
有序链表(升序)的实现:
public class CollectionDemo {
public static void main(String[] args) {
SortedList sortedList=new SortedList();
sortedList.insert(34);
sortedList.insert(21);
sortedList.insert(52);
sortedList.insert(93);
sortedList.insert(48);
sortedList.displayList();
}
}
class Link{
public long dData;
public Link next;
public Link(long dd){
dData=dd;
}
public void displayLink(){
System.out.print(dData+" ");
}
}
class SortedList{ //有序链表
private Link first;
public SortedList(){
first=null;
}
public boolean isEmpty(){
return (first==null);
}
public void insert(long key){ //按升序插入
Link newLink=new Link(key);
Link previous=null;
Link current=first;
while(current!=null&&key>current.dData){ //按升序查找key插入位置
previous=current; //前置位
current=current.next; //向后查询
}
//找到对应插入位置
if (previous==null) //插入为的前置位为空,直接插入
first=newLink;
else //前置位不为空,前置位previous连接key结点,key结点连接current,实现插入
previous.next=newLink;
newLink.next=current;
}
public Link remove(){ //删除操作
Link temp=first;
first=first.next;
return temp;
}
public void displayList(){ //输出数据
System.out.print("List(first-->last):");
Link current=first;
while(current!=null){
current.displayLink();
current=current.next;
}
System.out.println(" ");
}
}
按升序的有序链表结果:
八.双向链表
双向链表允许向前遍历,也允许向后遍历
1.遍历
双向链表的遍历方法displayForward()方法和普通链表的displayList()方法相同,displayBackward()方法与它们类似,但是从表尾开始,displayBackward方法部分代码如下:
Link current = first;
while(current!=null)
current = current.previous;
2.插入
双向链表的插入方法有三个,insertFirst()方法在表头插入,insertLast()方法在表尾插入,insertAfter()在某一特定元素后面插入
insertFirst()方法:除非链表是空的,否则insertFirst()方法把原来的first指向的链接点的previous字段指向新链接点,把新链接点的next字段指向前者,最后把first指向新结点
如果链表是空的,last字段必须改变,insertFirst核心部分代码:
if(isEmpty())
last=newLink;
else
first.previous=newLink;
newLink.next=first;
first=newLink;
insertLast()方法:该方法和insertFirst方法类似
insertAlter()方法:四个链接过程
实现代码:
if(current==last){
newLink.next=null;
last=newLink;
}else{
newLink.next=current.next;
current.next.previous=newLink;
}
newLink.preious=current;
current.next=newLink;
3.删除
删除方法有deleteFirst(),deleteLast()和deleteKey(),前两个较简单。在deleteKey()中要删除的链结点是current所值的链结点,如果输出的结点既不是第一个结点,也不是第一个结点,入图:
如果被删除的结点是第一个或最后一个,那就产生特殊情况,因为first或last必须指向前一个或后一个链结点,下面是实现代码:
if(current==first)
first=current.next;
else
current.previous.next=current.next;
if(current==last)
last=current.previous;
else
current.next.previous=current.previous;
双向链表实现代码:
class Link{
public long dData;
public Link next;
public Link previous;
public Link(long d){
dData=d;
}
public void displayLink(){
System.out.print(dData+" ");
}
}
//双向链表
class DoublyLinkedList{
private Link first;
private Link last;
public DoublyLinkedList(){
first=null;
last=null;
}
public boolean isEmpty(){
return first==null;
}
public void insertFirst(long dd){ //头插
Link newLink=new Link(dd);
if(isEmpty())
first=newLink;
else
first.previous=newLink; //newlink<--oldlast
newLink.next=first; //newlink-->oldlast
first=newLink; //first-->newlink;
}
public void insertLast(long dd){ //尾插
Link newLink=new Link(dd);
if (isEmpty()){
first=newLink;
}else{
last.next=newLink; //oldlast-->newlink
newLink.previous=last; //oldlas<--newlink
}
last=newLink; //last-->newlink
}
public Link deleteFirst(){ //头删除
Link temp=first;
if(first.next==null)
last=null;
else
first.next.previous=null; //oldlast-->null
first=first.next; //first-->oldlast
return temp;
}
public Link deleteLast(){ //尾删除
Link temp=last;
if (first.next==null)
last=null;
else
last.previous.next=null; //oldprivous-->null
last=last.previous; //last-->oldprivous
return temp;
}
public boolean insertAfter(long key,long dd){ //将dd插入到key后面
Link current=first;
while(current.dData!=key){
current=current.next;
if (current==null) //找不到插入对象的位置
return false;
}
//找到要插入的位置
Link newLink=new Link(dd);
if (current==last){ //如果插入的对象是最后一个
newLink.next=null; //newLink-->null
last=newLink; //last-->newlink
}else {
newLink.next=current.next; //如果不是最后一个,newlink-->oldnext
current.next.previous=newLink; //oldnext-->newlink
}
newLink.previous=current; //current<--newlink
current.next=newLink; //current-->newlink
return true;
}
public Link deleteKey(long key){ //删除指定元素
Link current=first;
while (current.dData!=key){
current=current.next;
if (current==null) //如果没有指定元素
return null;
}
//找到要删除的指定元素
if(current==first) //如果删除的元素是头结点
first=current.next; //first-->oldnext
else //不是头结点
current.previous.next=current.next; //oldprevious-->oldnext
if(current==last) //如果删除的元素是尾结点
last=current.previous; //last-->old.previous
else
current.next.previous=current.previous; //oldprevious<--oldnext
return current;
}
public void displayForward(){ //正向输出
System.out.print("List(first-->last):");
Link current=first;
while (current!=null){
current.displayLink();
current=current.next;
}
System.out.println(" ");
}
public void displayBackward() { //反向输出
System.out.print("List(last-->first):");
Link current = last;
while (current != null) {
current.displayLink();
current = current.previous;
}
System.out.println(" ");
}
}