您的位置:首页 > 理论基础 > 数据结构算法

数据结构之单向链表【java版】

2016-10-20 22:51 316 查看
一、链表带有头节点和当前节点两个成员变量,在进行操作的时候可以更加方便。而且都是带有空头结点的单向链表


package struct;

import java.util.Scanner;

/*
* 注:此处的两个成员变量权限不能为private,
* 因为private的权限公对本类访问
*/
class Node{
int data;//数据域
Node next;//指针域

public Node(int data){
this.data = data;
}

public Node(){

}
}

public class Link {
private Node head;//头结点
private Node current;//当前结点

/*
* 构造方法
*/
public Link(){
head = null;
current = head;
}

/*
* 方法:向链表中添加结点
* 如果头结点为空,则说明链表还没有创建,那就把新的结点赋给头结点,将当前结点指向头结点;
* 如果头结点不为空,则创建新结点,放在当前结点的后端,并将链表的当前索引向后移动一位。
*/
public void add(int data){
if(head == null){
head = new Node(data);
current = head;
}else{
current.next = new Node(data);
current = current.next;
}
}

/*
* 方法:遍历链表,即打印输入链表
* 如果头结点为空,则打印NULL;
* 如果头结点不为空,则让链表当前索引移动到头结点位置,从头结点开始进行遍历
*/
public void print(){
if (head == null) {
System.out.println("NULL");
return;
}else{
current = head;
while (current != null) {
System.out.println(current.data);
current = current.next;
}
}
}

/*
* 方法:获取链表的长度
* 如果头结点为空,要返回0;
* 如果头结点不为空,则将当前索引移到头结点位置,从头结点开始遍历统计长度
*/
public int length(){
int length = 0;
current = head;
while (current != null) {
length++;
current = current.next;
}
return length;
}

/*
* 方法:判断链表是否为空
* 如果头结点为空,返回true;否则返回false。
*/
public boolean isEmpty(){
if (head == null) {
return true;
}
return false;
}

/*
* 方法:合并两个有序(从小到大)链表,合并后有重复并且依然有序,并且返回合并后的链表
* 从两个链表的头结点开始比较,新链表就指向其中小的结点
*/
public Link merge(Link l1,Link l2){
Link l = new Link();
Node n1 = l1.head;
Node n2 = l2.head;
if(l1.isEmpty()){
return l2;//如果l1为空,则返回l2
}else if(l2.isEmpty()){
return l1;//如果l2为空,则返回l1
}
//l1当前索引值比l2的小,则将新链表头结点指向l1当前索引
if(n1.data < n2.data){
l.head =l.current = n1;
n1 = n1.next;
}else{//l2当前索引值小于等于l1的,则将新链表头结点指向l2当前索引
l.head = l.current = n2;
n2 = n2.next;
}
while(n1!=null && n2!=null){
//l1当前索引值比l2的小,则将新链表当前索引指向l1当前索引
if(n1.data < n2.data){
l.current.next = n1;
l.current = l.current.next;
n1 = n1.next;
}else{//l2当前索引值小于等于l1的,则将新链表当前索引指向l2当前索引
l.current.next = n2;
l.current = l.current.next;
n2 = n2.next;
}
}
//此时l2中的元素已经合并完了,继续合并l1中的元素
while(n1 != null){
l.current.next = n1;
l.current = l.current.next;
n1 = n1.next;
}
//此时l1中的元素已经合并完了,继续合并l2中的元素
while(n2 != null){
l.current.next = n2;
l.current = l.current.next;
n2 = n2.next;
}
return l;
}

/*
* 方法:返回带头节点的逆转链表
*
*/
public Link reverse(){
Link link = new Link();
link.head = new Node();
Node old_head,new_head,tmp;
new_head = null;
old_head = head.next;
while(old_head!=null){
tmp = old_head.next;
old_head.next = new_head;//将链表方向逆转
new_head = old_head;
old_head = tmp;
}
link.head.next = new_head;//将要返回链表的头结点指向新链表结点
return link;
}

public static void main(String[] args) {
Link link = new Link();
//向链表中添加数据
Scanner scan = new Scanner(System.in);
System.out.println("请输入数据……");
for (int i = 0; i < 6; i++) {
link.add(scan.nextInt());
}
Link l2 = new Link();
System.out.println("链表的长度为:"+link.length());
System.out.println("有一个空链表合并:");
Link lin = link.merge(link, l2);
lin.print();
Link l1 = new Link();
l1.add(3);
l1.add(5);
l1.add(6);
l1.add(8);
System.out.println("两个非空有序链表合并:");
lin = link.merge(link,l1);
lin.print();
Link ll = lin.reverse();
ll.print();
}
}

输出的结果为:

请输入数据……
1 2 3 4 5 6
链表的长度为:6
有一个空链表合并:
1  2  3  4  5  6
两个非空有序链表合并:
1  2  3  3  4  5  5  6  6  8
链表逆转后:
8  6  6  5  5  4  3  3  2  1

二、只有头结点的单向链表,为了方便操作,每次都要新建一个节点,代替链表的头节点。这里是不带空头节点的链表

package struct;

<pre name="code" class="java">class Node{
int data;//数据域
Node next;//指针域

public Node(int data){
this.data = data;
}

public Node(){

}
}


 /* * 不带头结点的链表 */public class LinkList {private Node head;// 构造函数public LinkList() {head = null;}// 向链表头部插入一个元素public void insertFirst(int val) {Node newlink = new Node();newlink.data = val;newlink.next = head;head = newlink;}// 向链表尾部部插入一个元素public void insertLast(int
val) {Node newlink = new Node();newlink.data = val;if(isEmpty()){head = newlink;return;}Node current = getCurrent();current.next = newlink;}// 从链表的头结点处删除一个元素public void deleteFirst() {Node temp = head.next;head = temp;}// 判断链表是否为空public boolean isEmpty() {return
(head == null);}// 打印链表(从头节点的元素开始打印)public void display() {Node current = head;if (isEmpty()) {System.out.println("NULL");return;}while (current != null) {System.out.print(current.data + " ");current = current.next;}System.out.println();}// 返回链表的当前节点public
Node getCurrent() {Node current = new Node();current = head;while (current.next != null) {current = current.next;}return current;}/* * 链表的逆转 * 1、将原头节点的下一个节点暂存在temp中; * 2、将原头节点指向新头节点; * 3、新头节点跳转到原头节点; * 4、原头节点跳转到temp; * 5、最后把新链表的头节点跳转到新头节点。 */public LinkList
reverse(){LinkList list = new LinkList();Node temp,old_head,new_head;old_head = head;new_head = null;while(old_head != null){temp = old_head.next;old_head.next = new_head;new_head = old_head;old_head = temp;}list.head = new_head;return list;}//判断元素是否存在于链表中public
boolean isExist(int val){Node current = head;while(current != null){if(current.data == val){return true;}current = current.next;}return false;}public static void main(String[] args) {LinkList l1 = new LinkList();l1.insertLast(1);l1.insertLast(2);l1.insertLast(3);l1.insertLast(4);l1.insertLast(5);System.out.println("链表1:");l1.display();LinkList
l2 = new LinkList();l2.insertLast(3);l2.insertLast(5);l2.insertLast(7);System.out.println("链表2:");l2.display();LinkList l = merge(l1,l2);System.out.println("两链表合并后:");l.display();l = l.reverse();System.out.println("链表逆转后:");l.display();}//合并两个有序单身链表public
static LinkList merge(LinkList l1,LinkList l2){LinkList link = new LinkList();if(l1.isEmpty()){//如果l1为空,则返回l2return l2;}if(l2.isEmpty()){//如果l2为空,则返回l1return l1;}Node link1 = l1.head;Node link2 = l2.head;Node linkHead = new Node();link.head = linkHead;while
(link1!=null && link2!=null){if(link1.data < link2.data){linkHead.next = link1;link1 = link1.next;linkHead = linkHead.next;}else{linkHead.next = link2;linkHead = linkHead.next;link2 = link2.next;}}while (link1 != null) {linkHead.next = link1;linkHead = linkHead.next;link1
= link1.next;}while (link2 != null) {linkHead.next = link2;linkHead = linkHead.next;link2 = link2.next;}link.head = link.head.next;//把头结点去掉return link;}}



输出的结果为:

链表1:
1  2  3  4  5
链表2:
3  5  7
两链表合并后:
1  2  3  3  4  5  5  7
链表逆转后:
7  5  5  4  3  3  2  1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 java