有序列表
有序列表简介
在有序链表中,数据是按照关键值有序排列的。一般在大多数需要使用有序数组的场合也可以使用有序链表。
与有序数组相比,有序链表的优点:插入的速度快(因为元素不需要移动);链表可以有效的使用内存,而数组只能局限于一个固定的大小中。
插入:先判断大小,然后在正确的位置插入
删除:删除头结点
查找:需要遍历
java实现
package link;
public class OrderLinkedListTest {
public static void main(String[] args) {
OrderLinkedList order = new OrderLinkedList();
order.insert(10);
order.insert(8);
order.insert(11);
order.display();
System.out.println(order.deleteHead());
order.display();
}
}
class OrderLinkedList{
private Node head;
private int size;
//构造方法
public OrderLinkedList(){
head = null;
size = 0;
}
//有序链表插入操作
public void insert(int data){
Node newNode = new Node(data);
Node previous = null;
Node current = head;
while (current!=null && data>current.data){
previous = current;
current = current.next;
}
if(previous == null){
//要插入的值比所有值都小
head = newNode;
head.next = current;
}else{
newNode.next = current;
previous.next = newNode;
}
size ++;
}
//判断链表是不是空链表
public boolean isEmpty(){
return size==0;
}
//链表删除头结点,默认链表中是有节点的
public int deleteHead(){
int obj = head.data;
head = head.next;
size --;
return obj;
}
//遍历输出所有node信息
public void display(){
if (size>0){
//不是空的
Node current = head;
int tmpSize = size;
if (tmpSize == 1){
System.out.println("[" + head.data + "]");
return; // 结束掉方法
}
while (tmpSize>0){
if (current == head){
System.out.print("[" + current.data + "->");
}else if(current.next == null){
//最后一个节点
System.out.print(current.data + "]");
}else {
System.out.print(current.data + "->");
}
tmpSize --;
current = current.next;
}
System.out.println();//输出一个换行符
}else {
//空列表
System.out.println("[]");
}
}
//定义一个私有类
private class Node{
private int data; //封装在节点里的数据
private Node next; //指针,指向下一个节点
//构造方法
public Node(int data){
this.data = data;
}
@Override
public String toString() {
return "Node [data=" + data + ", next=" + next + "]";
}
}
}
有序链表实现无序数组排序
冒泡排序,选择排序和插入排序方法时间复杂度都是O(N^2)
利用有序链表实现无序数组的排序肯定比以上三种方法效率高,但是需要开辟差不多两倍的空间,因为数组和链表必须在内存中同时存在。
package link;
import com.sun.org.apache.xpath.internal.objects.XString;
import java.util.Arrays;
public class OrderLinkedListTest {
public static void main(String[] args) {
// 生成随机数组
int[] list = new int[10];
for (int i=0;i<10;i++){
list[i] = (int)(Math.random()*100);
}
System.out.println(Arrays.toString(list));
//排序
OrderLinkedList order = new OrderLinkedList();
for(int i:list){
order.insert(i);
}
while (!order.isEmpty()){
System.out.print(Integer.toString(order.deleteHead()) + ' ');
}
}
}
class OrderLinkedList{
private Node head;
private int size;
//构造方法
public OrderLinkedList(){
head = null;
size = 0;
}
//有序链表插入操作
public void insert(int data){
Node newNode = new Node(data);
Node previous = null;
Node current = head;
while (current!=null && data>current.data){
previous = current;
current = current.next;
}
if(previous == null){
//要插入的值比所有值都小
head = newNode;
head.next = current;
}else{
newNode.next = current;
previous.next = newNode;
}
size ++;
}
//判断链表是不是空链表
public boolean isEmpty(){
return size==0;
}
//链表删除头结点,默认链表中是有节点的
public int deleteHead(){
int obj = head.data;
head = head.next;
size --;
return obj;
}
//遍历输出所有node信息
public void display(){
if (size>0){
//不是空的
Node current = head;
int tmpSize = size;
if (tmpSize == 1){
System.out.println("[" + head.data + "]");
return; // 结束掉方法
}
while (tmpSize>0){
if (current == head){
System.out.print("[" + current.data + "->");
}else if(current.next == null){
//最后一个节点
System.out.print(current.data + "]");
}else {
System.out.print(current.data + "->");
}
tmpSize --;
current = current.next;
}
System.out.println();//输出一个换行符
}else {
//空列表
System.out.println("[]");
}
}
//定义一个私有类
private class Node{
private int data; //封装在节点里的数据
private Node next; //指针,指向下一个节点
//构造方法
public Node(int data){
this.data = data;
}
@Override
public String toString() {
return "Node [data=" + data + ", next=" + next + "]";
}
}
}
双向链表
双向链表简介
双向链表可以从两个方向遍历。
在双端列表基础上,给每个节点添加了一个previous指针,指向前一个节点。
java实现双向链表
package link;
public class DoubleWayLinkedListTest {
public static void main(String[] args) {
DoubleWayLinkedList doubleWayLinkedList = new DoubleWayLinkedList();
doubleWayLinkedList.addHead(1);
doubleWayLinkedList.addHead(2);
doubleWayLinkedList.addHead(3);
doubleWayLinkedList.addTail(4);
doubleWayLinkedList.addTail(5);
doubleWayLinkedList.addTail(6);
doubleWayLinkedList.display();
System.out.println(doubleWayLinkedList.delete(1));
doubleWayLinkedList.display();
System.out.println(doubleWayLinkedList.deleteHead());
doubleWayLinkedList.display();
while (!doubleWayLinkedList.isEmpty()){
System.out.println(doubleWayLinkedList.deleteTail());
}
// System.out.println(doubleLinkedList.deleteTail());
// doubleLinkedList.display();
}
}
class DoubleWayLinkedList{
private int size; //链表的节点数
private Node head; // head是头结点的指针,引入了一个新类型,node
private Node tail; //指向尾结点的指针
//构造方法
public DoubleWayLinkedList(){
size = 0;
head = null;
tail = null;
}
//向链表中添加节点(添加到头部)
public Object addHead(Object data){
Node newNode = new Node(data);
if(size == 0){
//空链表
head = newNode;
tail = newNode;
newNode.prev = null;
newNode.next = null;
}else {
//非空链表
newNode.next = head;
newNode.prev = null;
head.prev = newNode;
head = newNode;
}
size ++;
return newNode;
}
//添加尾结点
public Object addTail(Object data){
Node newNode = new Node(data);
if(size == 0) {
//空链表
head = newNode;
tail = newNode;
newNode.prev = null;
newNode.next = null;
}else {
tail.next = newNode;
newNode.prev = tail;
newNode.next = null;
tail = newNode;
}
size ++;
return newNode;
}
//链表删除头结点
public Object deleteHead(){
Object obj = null;
if(size == 0){
//空链表
return obj;
}else if(size == 1){
//链表中只有一个节点
obj = head.data;
head = null;
tail = null;
}else{
obj = head.data;
head =head.next;
head.prev = null;
}
size --;
return obj;
}
//删除尾部节点
public Object deleteTail(){
Object obj = null;
if(size == 0){
//空链表
return obj;
}else if(size == 1) {
//链表中只有一个节点
obj = tail.data;
head = null;
tail = null;
}else {
obj = tail.data;
tail = tail.prev;
tail.next = null;
}
size --;
return obj;
}
//判断链表是不是空链表
public boolean isEmpty(){
return size==0;
}
//删除指定节点,删除成功返回true,失败返回false
public boolean delete(Object value){
if(isEmpty()){
//空表
return false;
}
//不是空表
Node current = head;
Node previous = head;//上一个变量
while (!value.equals(current.data)){
if (current.next == null){
//已经扫描到了尾结点,且没找到数据
return false;
}else{
//还没到尾结点
previous = current;
current = current.next;
}
}
// 循环终止了,还会继续执行下面的语句,证明已经找到了要找的节点
//删除找到的节点
if(size == 1){
head = null;
tail = null;
}else if(current == head){
//头部节点
head = head.next;
head.prev = null;
}else if(current == tail){
//尾部节点
previous.next = null;
tail = previous;
}else {
previous.next = current.next;
current.next.prev = previous;
}
size --;
return true;
}
//遍历输出所有node信息
public void display(){
if (size>0){
//不是空的
Node current = head;
int tmpSize = size;
if (tmpSize == 1){
System.out.println("[" + head.data + "]");
return; // 结束掉方法
}
while (tmpSize>0){
if (current == head){
System.out.print("[" + current.data + "->");
}else if(current.next == null){
//最后一个节点
System.out.print(current.data + "]");
}else {
System.out.print(current.data + "->");
}
tmpSize --;
current = current.next;
}
System.out.println();//输出一个换行符
}else {
//空列表
System.out.println("[]");
}
}
//获取节点个数
public int getSize(){
return size;
}
//定义一个私有类
private class Node{
private Object data; //封装在节点里的数据
private Node next; //指针,指向下一个节点
private Node prev; //指针,指向上一个节点
//构造方法
public Node(Object data){
this.data = data;
}
@Override
public String toString() {
return "Node [data=" + data + ", next=" + next + ", prev=" + prev + "]";
}
}
}