目录
-
由节点构成的动态数据结构,链表
package com.suanfa.linkedlist;
/**
* 链表,动态数据结构,由节点构成,
* 如1-2-3-4-5-6 ,每个数字都存放在一个节点类中
* @author Administrator
*/
public class LinkedList<E> {
/**
* 节点类,包含节点元素和对其他节点的指向
* @author Administrator
*
*/
private class Node {
public E e;// 元素
public Node next;// 节点之间的指针
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
private Node dummyHead;// 虚拟头节点,是头结点的前一个节点,用来方便向链表头插入元素
private int size;// 节点个数
/**
* 构造函数
*/
public LinkedList() {
dummyHead=new Node();
size = 0;
}
/**
* 获取链表中的元素个数
*
* @return
*/
public int getSize() {
return size;
}
/**
* 判断链表是否为空
*
* @return
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 在链表头添加新的元素
*
* @param e
*/
public void addFirst(E e) {
/*
// Node node=new Node(e);新建一个节点
// node.next=head;新节点指向旧链表的头节点
// head=node;更新链表头
head = new Node(e, head);
size++;// 维护元素个数
*/
add(0,e);
}
/**
* 在链表的index(0-based)位置添加新的元素e
* 在链表中不是一个常用的操作,练习用:)
* @param index
* @param e
*/
public void add(int index, E e) {
if (index < 0 || index > size)
throw new IllegalArgumentException("Add failed. Illegal index.");
/*//如果位置是0,则是开头位置
if (index == 0)
addFirst(e);
else {
Node prev = head;
// 记录一个前标,让标记移动到坐标的前一个节点
// 把新节点的next指向前标的next,然后把prev的节点的next指向新节点
for (int i = 0; i < index - 1; i++) {
prev = prev.next;
}
// Node node = new Node(e);
// node.next = prev.next;
// prev.next = node;
prev.next = new Node(e, prev.next);
size++;
}*/
Node prev = dummyHead;
for(int i = 0 ; i < index ; i ++)
prev = prev.next;
prev.next = new Node(e, prev.next);
size ++;
}
/**
*在链表末尾添加新的元素e
* @param e
*/
public void addLast(E e){
add(size, e);
}
/**
* 获得链表的第index(0-based)个位置的元素
* 在链表中不是一个常用的操作,练习用:)
* @param index
* @return
*/
public E get(int index){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Get failed. Illegal index.");
//当前节点为虚拟节点的下一个节点,也就是真正的链表头
Node cur = dummyHead.next;
for(int i = 0 ; i < index ; i ++)
cur = cur.next;
return cur.e;
}
/**获得链表的第一个元素
*
* @return
*/
public E getFirst(){
return get(0);
}
/**
* 获得链表的最后一个元素
* @return
*/
public E getLast(){
return get(size - 1);
}
/**
* 修改链表的第index(0-based)个位置的元素为e
* 在链表中不是一个常用的操作,练习用:)
* @param index
* @param e
*/
public void set(int index, E e){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Set failed. Illegal index.");
Node cur = dummyHead.next;
for(int i = 0 ; i < index ; i ++)
cur = cur.next;
cur.e = e;
}
/**
* 查找链表中是否有元素e
* @param e
* @return
*/
public boolean contains(E e){
Node cur = dummyHead.next;
while(cur != null){
if(cur.e.equals(e))
return true;
cur = cur.next;
}
return false;
}
/**
* 从链表中删除index(0-based)位置的元素, 返回删除的元素
* 在链表中不是一个常用的操作,练习用:)
* @param index
* @return
*/
public E remove(int index){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Remove failed. Index is illegal.");
//待删除节点的前一个节点
Node prev = dummyHead;
for(int i = 0 ; i < index ; i ++)
prev = prev.next;
Node retNode = prev.next;
//让待删除节点的前一个节点指向删除节点的后一个节点
//把删除节点跳过去
prev.next = retNode.next;
//然后让删除的节点指向null,让jvm回收
retNode.next = null;
size --;
return retNode.e;
}
/**
* 从链表中删除第一个元素, 返回删除的元素
* @return
*/
public E removeFirst(){
return remove(0);
}
/**
* 从链表中删除最后一个元素, 返回删除的元素
* @return
*/
public E removeLast(){
return remove(size - 1);
}
/**
* 从链表中删除元素e
* @param e
*/
public void removeElement(E e){
Node prev = dummyHead;
while(prev.next != null){
if(prev.next.e.equals(e))
break;
prev = prev.next;
}
if(prev.next != null){
Node delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
size --;
}
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
// Node cur = dummyHead.next;
// while(cur != null){
// res.append(cur + "->");
// cur = cur.next;
// }
for(Node cur = dummyHead.next ; cur != null ; cur = cur.next)
res.append(cur + "->");
res.append("NULL");
return res.toString();
}
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<Integer>();
for(int i = 0 ; i < 5 ; i ++){
linkedList.addFirst(i);
System.out.println(linkedList);
}
linkedList.add(2, 666);
System.out.println(linkedList);
}
}
-
栈的方法接口
package com.suanfa.linkedlist;
/**
* 栈的方法接口
* @author Administrator
*
*/
public interface Stack<E> {
/**
* 查询栈的大小
* @return
*/
int getSize();
/**
* 判断栈是否为空
* @return
*/
boolean isEmpty();
/**
* 入栈
* @param e
*/
void push(E e);
/**
* 出栈
* @return
*/
E poop();
/**
* 查看栈顶元素
* @return
*/
E peek();
}
-
基于链表实现的栈
package com.suanfa.linkedlist;
/**
* 基于链表实现的栈
* @author Administrator
*
* @param <E>
*/
public class LinkedListStack<E> implements Stack<E> {
private LinkedList<E> list;
public LinkedListStack(){
list = new LinkedList<E>();
}
/**
* 查询栈的大小
*/
@Override
public int getSize() {
return list.getSize();
}
/**
* 判断栈是否为空
*/
@Override
public boolean isEmpty() {
return list.isEmpty();
}
/**
* 入栈
*/
@Override
public void push(E e) {
list.addFirst(e);
}
/**
* 出栈
*/
@Override
public E poop() {
return list.removeFirst();
}
/**
* 查看栈顶元素
*/
@Override
public E peek() {
return list.getFirst();
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Stack: top ");
res.append(list);
return res.toString();
}
public static void main(String[] args) {
LinkedListStack<Integer> stack = new LinkedListStack<Integer>();
for(int i = 0 ; i < 5 ; i ++){
stack.push(i);
System.out.println(stack);
}
stack.poop();
System.out.println(stack);
}
}
-
队列接口
package com.suanfa.linkedlist;
/**
* 队列接口
* @author Administrator
*
* @param <E>
*/
public interface Queue<E> {
int getSize();
boolean isEmpty();
void enqueue(E e);
E dequeue();
E getFront();
}
-
基于链表的队列
package com.suanfa.linkedlist;
/**
* 基于链表的队列
* @author Administrator
*
* @param <E>
*/
public class LinkedListQueue<E> implements Queue<E> {
/**
* 节点类,包含节点元素和对其他节点的指向
* @author Administrator
*
*/
private class Node{
public E e;
public Node next;
public Node(E e, Node next){
this.e = e;
this.next = next;
}
public Node(E e){
this(e, null);
}
public Node(){
this(null, null);
}
@Override
public String toString(){
return e.toString();
}
}
//声明头节点和尾节点
private Node head, tail;
//声明元素的个数
private int size;
/**
* 构造方法
*/
public LinkedListQueue(){
head = null;
tail = null;
size = 0;
}
/**
* 获取队列元素个数
*/
@Override
public int getSize(){
return size;
}
/**
* 判断队列是否为空
*/
@Override
public boolean isEmpty(){
return size == 0;
}
/**
* 入队
*/
@Override
public void enqueue(E e){
//当第一个元素入队的时候,头和尾都指向第一个节点
if(tail == null){
tail = new Node(e);
head = tail;
}
//否则尾节点指向新节点,并维护尾节点
else{
tail.next = new Node(e);
tail = tail.next;
}
size ++;
}
/**
* 出队
*/
@Override
public E dequeue(){
//如果队列为空,抛出异常
if(isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
//记录头节点
Node retNode = head;
//头节点向尾部移动一位
head = head.next;
//队首节点指向null,让JVM回收
retNode.next = null;
//如果队列没有节点了,头和尾都变为null
if(head == null)
tail = null;
size --;
return retNode.e;
}
/**
* 获取队首元素
*/
@Override
public E getFront(){
if(isEmpty())
throw new IllegalArgumentException("Queue is empty.");
return head.e;
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("Queue: front ");
Node cur = head;
while(cur != null) {
res.append(cur + "->");
cur = cur.next;
}
res.append("NULL tail");
return res.toString();
}
public static void main(String[] args){
LinkedListQueue<Integer> queue = new LinkedListQueue<Integer>();
for(int i = 0 ; i < 10 ; i ++){
queue.enqueue(i);
System.out.println(queue);
if(i % 3 == 2){
queue.dequeue();
System.out.println(queue);
}
}
}
}
-
删除链表中全部元素val,不使用虚拟节点
package com.suanfa.linkedlist;
/**
* 删除链表中全部元素val,不使用虚拟节点
*
* @author Administrator
*
*/
public class Solution {
/**
* 节点类
* @author Administrator
*
*/
class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
val = x;
}
}
public ListNode removeElements(ListNode head, int val) {
//如果链表只有一个节点,当节点不为空并且节点的元素是要删除的元素,执行删除
while(head != null && head.val == val){
ListNode delNode = head;
head = head.next;
delNode.next = null;
}
//如果链表为空,返回链表
if(head == null)
return head;
//如果第一个节点不是要删除的节点,向下遍历
ListNode prev = head;
while(prev.next != null){
if(prev.next.val == val) {
ListNode delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
}
else
prev = prev.next;
}
return head;
}
}
-
删除链表中全部元素val,使用虚拟节点
package com.suanfa.linkedlist;
/**
* 删除链表中全部元素val,使用虚拟节点
*
* @author Administrator
*
*/
public class Solution2 {
/**
* 节点类
* @author Administrator
*
*/
class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
val = x;
}
}
public ListNode removeElements(ListNode head, int val) {
//新建一个虚拟节点
ListNode dummyHead = new ListNode(-1);
//虚拟节点指向链表头
dummyHead.next = head;
//从虚拟节点开始查找需要删除的节点
ListNode prev = dummyHead;
while(prev.next != null){
if(prev.next.val == val)
prev.next = prev.next.next;
else
prev = prev.next;
}
return dummyHead.next;
}
}
-
用递归算法删除链表中所有元素val
package com.suanfa.linkedlist;
import com.suanfa.linkedlist.Solution2.ListNode;
/**
* 用递归算法删除链表中所有元素val
*
* @author Administrator
*
*/
public class Solution3 {
/**
* 节点类
* @author Administrator
*
*/
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
val = x;
}
/**
* 构造函数,把一个数组转换为一个链表
* @param arr
*/
public ListNode(int[] arr) {
if (arr == null || arr.length == 0)
throw new IllegalArgumentException("arr can not be empty");
//链表头为数组第一个元素
this.val = arr[0];
ListNode cur = this;
//把数组中其他元素拼接成链表
for (int i = 1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
}
}
// 以当前节点为头结点的链表信息字符串
@Override
public String toString() {
StringBuilder s = new StringBuilder();
ListNode cur = this;
while (cur != null) {
s.append(cur.val + "->");
cur = cur.next;
}
s.append("NULL");
return s.toString();
}
}
/**
* 用递归算法删除链表中的所有指定元素
* @param head
* @param val
* @return
*/
public ListNode removeElements(ListNode head, int val) {
//如果链表是空,返回链表或者null
if (head == null)
return head;
/*1->2->6->3->4->5->6
* 第一次:1.next=(1)->1.next=2-3-4-5-null 返回最终结果1-2-3-4-5-null
* 第二次:2.next=(2)->2.next=3-4-5-null 返回到(1)为2-3-4-5-null
* 第三次:6.next=(3)->6.next=3-4-5-null 返回到(2)为3-4-5-null
* 第四次:3.next=(4)->3.next=4-5-null 返回到(3)为3-4-5-null
* 第五次:4.next=(5)->4.next=5-null 返回到(4)为4-5-null
* 第六次:5.next=(6)->5.next=null 返回到(5)为5-null
* 第七次:6.next=null->返回到(6)为null
*
*/
head.next = removeElements(head.next, val);
return head.val == val ? head.next : head;
}
public static void main(String[] args) {
int[] nums = { 1, 2, 6, 3, 4, 5, 6 };
ListNode head =new Solution3().new ListNode(nums);
System.out.println(head);
ListNode res = (new Solution3()).removeElements(head, 6);
System.out.println(res);
}
}
//通过递归深度和打印输出查看递归过程
/*public class Solution3 {
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
val = x;
}
public ListNode(int[] arr) {
if (arr == null || arr.length == 0)
throw new IllegalArgumentException("arr can not be empty");
//链表头为数组第一个元素
this.val = arr[0];
ListNode cur = this;
//把数组中其他元素拼接成链表
for (int i = 1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
}
}
// 以当前节点为头结点的链表信息字符串
@Override
public String toString() {
StringBuilder s = new StringBuilder();
ListNode cur = this;
while (cur != null) {
s.append(cur.val + "->");
cur = cur.next;
}
s.append("NULL");
return s.toString();
}
}
public ListNode removeElements(ListNode head, int val, int depth) {
String depthString = generateDepthString(depth);
System.out.print(depthString);
System.out.println("Call: remove " + val + " in " + head);
if(head == null){
System.out.print(depthString);
System.out.println("Return: " + head);
return head;
}
ListNode res = removeElements(head.next, val, depth + 1);
System.out.print(depthString);
System.out.println("After remove " + val + ": " + res);
ListNode ret;
if(head.val == val)
ret = res;
else{
head.next = res;
ret = head;
}
System.out.print(depthString);
System.out.println("Return: " + ret);
return ret;
}
private String generateDepthString(int depth){
StringBuilder res = new StringBuilder();
for(int i = 0 ; i < depth ; i ++)
res.append("--");
return res.toString();
}
public static void main(String[] args) {
int[] nums = {1, 2, 6, 3, 4, 5, 6};
ListNode head = new Solution3().new ListNode(nums);
System.out.println(head);
ListNode res = (new Solution3()).removeElements(head, 6, 0);
System.out.println(res);
}
}*/
-
使用递归函数求数组和
package com.suanfa.linkedlist;
/**
* 使用递归函数求数组和
* @author Administrator
*
*/
public class Sum {
/**
* 计算arr[l...n)这个区间内所有数字的和
* @param arr
* @param l
* @return
*/
public static int sum(int[]arr,int l){
if(l==arr.length){
return 0;
}
return arr[l]+sum(arr,l+1);
}
public static int sum(int[]arr){
return sum(arr,0);
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5, 6, 7, 8};
System.out.println(sum(nums));
}
}