JAVA链表实现与链表的逆序

1.链表

        链表有单链表还有双向链表,在java中每个节点都是一个类,这里声明了内部类,为了方便插入和删除,有时会在,链表的表头加上哨兵(形成有哨兵的循环或双向循环链表),这样的插入删除就不用考虑当插入删除的元素在边界的情况,方便,至于哨兵你可能觉得没什么用,其实他可以存储链表的许多信息,比如你每次查找一个元素,在无哨兵时,使用P!=null,使用哨兵,可以存储要查找的元素,退出时,就要判断是不是哨兵。

2.链表的实现与逆序

若想代码写得快,必须清楚每次交换插入,产生的状态和性质。在写代码时,一个节点指错了下一个节点,导致调了好长时间,一定要想清楚每次变换的状态结果。下面使用了两种方法实现,链表的逆序,这两个思路都是插入排序的思想,只是迭代反向不同。

思路一:从第n-1个元素开始向前迭代,一次插入到链表结尾,在为双向链表并且含有尾节点时,时间复杂度为:n,在当链表为 n的平方。因为还要查找节点。

思路二:从第2-n个节点一次向后迭代,插入到head节点位置,一次向后就能每次使用next保存下一次要插入的元素,一路走来,不用查找节点。

同样的思路不同的方向,向前面插向后面插,双向思考

代码如下:

class List<T> {
	private static class Node<T>{
		private T key;
		Node<T> next;
		public Node(T key,Node<T> next)
		{
			this.key=key;
			this.next=next;
		}
	}
	private int size;
	private Node<T> head;
	public List(){
		size=0;
		head=null;
	}
	public int size()
	{
		return size;
	}
	public boolean isEmpty()
	{
		if(size==0)
			return true;
		else
			return false;
	}
	public void insert(T key)
	{
		head=new Node<T>(key,head);
		size++;
	}
	public T front()
	{
		return  head.key;
	}
	public T get(int index)
	{
		if(index>=size||index<0)
			return null;
		int i=0;
		Node<T>p=head;
		while(i++<index)
			p=p.next;
		return p.key;
	}
	public T delete(){
		T x=head.key;
		head = head.next;
		size--;
		return x;
	}
	public void delete(T key){
		Node<T>node=searchNode(key);
		if(node==null)
			return ;

		if(size==1)
			head=null;
		else
		{
		    Node<T>pre=head;
		    while(pre.next!=null&&pre.next!=node)
			pre=pre.next;
		    pre.next=node.next;
		}
		size--;
	}
	public Node<T> searchNode(T key)
	{
		Node<T> p= head;
		int i=0;
		while(p!=null&&p.key!=key)
			p=p.next;
		return p;
	}
	public int searchIndex(T x)
	{
		Node<T> p= head;
		int i=0;

		while(p!=null&&p.key!=x)
		{
			i++;
			p=p.next;

		}
		if(p!=null)
		return i;
		return -1;
	}
	public Node<T> getNode(int index)
	{
		if(index<0&&index>=size)
			return null;
		int i=0;
		Node<T>p=head;
		while(i++<index)
			p=p.next;
		return p;
	}
	/**
	 * 求链表的逆序  注意一定要链接节点时 连接对
	 * 思路一:这个比较麻烦:是把前面的元素从后向前一次放在链表结尾
	 * 还要查找元素节点,查找过程为n所以时间复杂度已经为 :n的平方 了
	 */
	public void reverse(){
		if(size<=1)
			return ;
		int i=size-2;
		Node<T>tail=getNode(size-1);
		while(i>=0)
		{
             Node<T>e=getNode(i);
             if(e!=head)
             {
            	 Node<T>pre=getNode(i-1);
                 tail.next=e;
                 pre.next=e.next;
                 tail=e;
                 tail.next=null;
             }
             else
             {
            	 tail.next=head;
            	 tail=head;
            	 head=head.next;
            	 tail.next=null;
             }
             i--;
		}
	}

	/**
	 * 思路二: 从后面像最前面插入,插入排序的思想
	 */
	public void reverse2()
	{
		if(size<=1)
			return ;
		int i=1;
		Node<T>pre,insertNode,next;
		pre=head;
		next=head.next;//每个要插入元素的头结点都是最初的头结点
		while(i++<size)
		{
			insertNode=next;
			if(next.next!=null)
			next=next.next;
            pre.next=insertNode.next;
			insertNode.next=head;
			head=insertNode;
		}

	}
	/*使用java的值传递,是复制了一份引用的副本,不是原来的引用
	 * ,虽然指向相同,这样是不能把链表转换为逆序的
	 * public void swap(Node<T>head)

	{
		if(head.next!=null)
		{
			Node<T>p=head;
			swap(p.next);
			T key=head.key;
			while(p!=null)
				p=p.next;
			p.next=head;
			head=p.next;
		}

	}*/
}
public class SingleList {
    public static  void main(String args[])
    {
    	List<Integer> list=new List<Integer>();
    	list.insert(1);
    	list.insert(2);
    	list.insert(3);
    	list.insert(4);
    	list.insert(5);
    	list.reverse2();
    	System.out.println(list.get(0)+" "+list.get(1)+" "+list.get(2)+" "+list.get(3)+" "+list.get(4)+" ");
    }
}
时间: 2024-08-28 06:57:01

JAVA链表实现与链表的逆序的相关文章

设计鲁棒性的方法:输入一个链表的头结点,逆序遍历打印该链表出来

之前有过整理链表等的概念和基本算法.比较重要的是插入,删除,遍历,建表(尾插法,头插法) 回忆链表尾部插入结点:  1 #include <iostream> 2 using namespace std; 3  4 typedef struct Node{ 5     int data;//数据域 6     Node *next;//指针域 7 } Node, *List; 8  9 //在单链表的末位添加一个结点10 void addNode(List *head, int value)1

用单链表来实现数据的逆序

#include<stdio.h>#include<stdlib.h> typedef struct node{ int data;//节点数据 struct node *next;//节点指针,该指针指向该节点的下一节点}listnode,*list;//list指向该节点//初始化单链表list initlist(void){ list mylist=malloc(sizeof(listnode));//malloc分配空间,创建节点,以此为头节点,并用指针mylist指向它

java版的单向链表的逆序输出

将单向链表逆序输出,方法有三种: a.遍历链表,将每个节点的内容存入一个数组中,然后逆序输出数组(最简单的做法) b.使用栈来逆序输出 c.直接将链表逆序然后输出(本文采用的方法) 先介绍算法: 1). 若链表为空或只有一个元素,则直接返回: 2). 设置两个前后相邻的指针p,q. 将p所指向的节点作为q指向节点的后继: 3). 重复2),直到q为空 4). 调整链表头和链表尾 示例:以逆序A->B->C->D为例,图示如下 package com.moluo.shujujiegou;

C++ 递归和非递归实现链表逆序

测试环境:vs2010  windows7 逆序分别采用递归调用和链表头插法实现逆序. 具体代码如下: #include<iostream> #include<stdlib.h> using namespace std; class LinkList { private: struct Node { struct Node *next; int value; }; Node *phead; void reverse_use_recursion(Node *pnode) { if(p

链表逆序+判断链表是否回文

单链表逆序详解 1.具有链表头的单链表 假设需要逆序的单链表为: 则逆序以后的链表为: 过程: (1)取p1指向header->next (p1=stu->next);p2保留p1->next(p2=p1->next);将p1->next置为NULL,因为单链表逆序以后,当前的p1节点为尾节点 p1->next=NULL; (2)取p3保留p2->next (p3=p2->next);将p2插入p1之前(p2->next = p1);p1指向p2指向的

数据结构:链表的基本操作(创建,删除,插入,逆序,摧毁)

代码注释比较详细: #include <iostream> #include <cstdlib> using namespace std; struct Node{ int data; Node* next; }; Node* head = NULL; bool create() { head = (Node*)malloc(sizeof(Node)); if(NULL == head) return false; head->data = 0; head->next

链表逆序2

问题来源:选自LeetCode 92:反转链表 II 问题描述: 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, m = 2, n = 4 输出: 1->4->3->2->5->NULL 题目给定信息: 问题分析: 这道题也是要求实现链表的逆序,但是不同的地方在于要求在链表中规定的某一部分实现链表的逆序.那么我们可以把这个链表分为三部分

如何实现链表的逆序

1 单向链表的反转 问题描述: 给定一个带头结点的单链表,请将其逆序.即如果单链表原来为head -->1 --> 2 --> 3 --> 4 --> 5,那么逆序后变为head --> 5 --> 4 --> 3 --> 2 --> 1. 解决过程: 给定一个单向链表1-->2-->3,通过下面的示意图,看如何一步一步的将单向列表反转. 代码实现: 1 class Node(object): 2 def __init__(self,

字符逆序(一)

将一个字符串str的内容颠倒过来,并输出.str的长度不超过100个字符. 如:输入"I am a student",输出"tneduts a ma I". package test; import java.util.Scanner; /* 一个句子单词逆序.句子逆序 */ public class exam09 { public static void main(String[] args) { Scanner scanner = new Scanner(Sys