package ccnu.linkList;
public class LinkList {
private Node first; // 第一个节点
private Node rear; // 最后一个节点
private int size; // 当前链表的大小
public LinkList() {
this.first = null;
this.rear = null;
this.size = 0;
}
/**
* 链表中的元素的个数
*
* @return 返回该链表中元素的个数
*/
public int size() {
return size;
}
/**
* 判断当前对象是否为空,如果空,当且仅当没有任何元素,{@link #size()}为0
*
* @return true,如果{@link #size()}为0,否则false
*/
public boolean isEmpty() {
if (size == 0) {
return true;
}
return false;
}
/**
* 头插法,在链表的头部插入节点
*
* @param data
* 插入节点的数据
* @see #insertAtRear(int)
* @see #insertByIndex(int, int)
*/
public void insertAtHead(int data) {
Node node = new Node(data);
size++;
if (size == 1) { // 第一个节点采用头插法
first = node;
rear = node;
} else {
node.next = first; // 当前节点插入到最前
first = node;
}
}
/**
* 尾插法,在链表的尾部插入节点
*
* @param data
* 插入节点的数据
* @see #insertAtHead(int)
* @see #insertByIndex(int, int)
*/
public void insertAtRear(int data) {
Node node = new Node(data);
size++;
if (size == 1) { // 第一个节点采用尾插法
first = node;
rear = node;
} else {
rear.next = node; // 当前节点插入到最后
rear = node;
}
}
/**
* 指定索引位置插入节点(其后面)
*
* @param index
* 插入位置
* @param data
* 所要插入节点的数据
* @see #insertAtHead(int)
* @see #insertAtRear(int)
*/
public void insertByIndex(int index, int data) {
if (index < 0 || index > (size - 1)) {
return;
}
int pos = 0;
Node current = first;
Node node = new Node(data);
while (pos != index) {
pos++;
current = current.next;
}
node.next = current.next;
current.next = node;
if(node.next == null){ // 插入的位置为最后一个位置
rear = node;
}
size++;
}
/**
* 删除任意索引位置的节点,并返回该节点,返回null,如果位置不合法
*
* @param index
* 指定位置
* @return 返回将要删除的节点
* @see #deleteByData(int, boolean)
* @see #deleteByData(int)
*/
public Node deleteByIndex(int index) {
Node current = first; // 当前节点
Node previous = null; // 当前节点的前一个节点
int pos = 0;
if (index < 0 || index >= size) { // 超出索引范围
return null;
} else {
while (pos != index) {
pos++;
previous = current;
current = current.next;
}
}
if (current == first) { // 删除节点为第一个节点
first = first.next;
} else {
previous.next = current.next;
}
if (current.next == null) { // 删除节点为最后一个节点
rear = previous;
}
size--;
// current.next = null; // 仅保留数据域
return current; // 返回指定索引的节点
}
/**
* 删除链表中指定数据的节点,并返回删除的节点(集)
*
* @param data
* 数据域
* @param flag
* true表示删除所有data元素,缺省为false
* @return 表示"删除链表"的第一个节点
* @see #deleteByData(int)
*/
public Node deleteByData(int data, boolean flag) { // flag = true
// 表示删除所有值为data的节点,否则只删除出现的第一个值为data节点
Node newFirst = null; // 所有删除指定data的链表的第一个节点
Node newRear = null;
int pos = 0;
Node current = first;
if (flag == false) {
while (current != null) {
if (current.data == data) {
deleteByIndex(pos);
// return (newFirst = current);
newFirst = current;
newFirst.next = null; // 只保留数据域
break;
}
current = current.next;
pos++; // 记录当前索引位置
}
} else {
while (current != null) {
if (current.data == data) {
deleteByIndex(pos);
pos--; // 删除链表中一个节点后,当前最新链表元素少一个,对应的索引也要减少
if (newFirst == null) { // 在"删除链表"中插入第一个节点
newFirst = current;
newRear = current;
} else {
newRear.next = current;
newRear = current;
}
}
current = current.next;
pos++;
}
}
return newFirst;
}
/**
* 仅删除链表中的第一个为指定数据的节点,并返回这个节点
*
* @param data
* 指定数据
* @return 删除的节点
* @see #deleteByData(int, boolean)
*/
public Node deleteByData(int data) {
return deleteByData(data, false);
}
/**
* 根据指定数据在链表中获取其位置 (首次出现)
*
* @param data
* 数据
* @return 数据的位置,返回-1,如果链表中木有这个数据
*/
public int findByData(int data) {
Node current = first;
int pos = 0;
while (current != null) {
if (current.data == data) {
return pos;
}
current = current.next;
pos++;
}
return -1;
}
/**
* 根据指定的位置获取这个节点
*
* @param index
* 索引位置
* @return 指定位置的节点
*/
public Node findByIndex(int index) {
Node current = first;
int pos = 0;
while (current != null) {
if (pos == index) {
return current;
}
current = current.next;
pos++;
}
return null;
}
/**
* 用新数据替代指定数据 (修改一个,如果存在)
*
* @param oldData
* 待查数据
* @param newData
* 新数据
* @see #replaceAll(int, int)
*/
public void replace(int oldData, int newData) {
Node current = first;
while (current != null) {
if (current.data == oldData) {
current.data = newData;
return;
}
current = current.next;
}
}
/**
* 用新数据替代指定数据 (修改所有,如果存在)
*
* @param oldData
* 待查数据
* @param newData
* 新数据
* @see #replace(int, int)
*/
public void replaceAll(int oldData, int newData) {
Node current = first;
while (current != null) {
if (current.data == oldData) {
current.data = newData;
}
current = current.next;
}
}
/**
* 显示整个链表的信息
*
*/
public void displayAllNodes() {
Node current = first;
while (current != null) {
current.display();
current = current.next;
}
}
/**
*
* 反向输出单链表所有值(递归)
*/
public void reverseOutput(Node first){
if(first == null){
return;
}
Node cur = first;
if(cur.next == null){
System.out.print(new Integer(cur.data).toString() + " ");
}else{
reverseOutput(cur.next);
System.out.print(new Integer(cur.data).toString() + " ");
}
}
/**
* 反向输出单链表所有值(栈存储方式)
*
*/
public void reverseOutput2(Node first){
List<Node> l = new LinkedList<Node>();
Node node = first;
while(node != null){
l.add(node);
node = node.next;
}
while(l.size() != 0){
System.out.print(new Integer(l.remove(l.size()-1).data).toString() + " ");
}
}
/**
* 将原单链表进行倒置
* @param first 原单链表的头结点
* @return 倒置后单链表的头结点
*/
public Node reverseList(Node first){
if(first == null){
return null;
}
Node p, q;
p = first.next;
first.next = null;
while(p != null){
q = p;
p = p.next;
q.next = first;
first = q;
}
return first;
}
}
package ccnu.linkList;
public class Node {
// 私有,设置getter和setter
protected Node next; // 指针域
protected int data; // 数据域
public Node() {
this(0);
}
public Node(int data) {
this.data = data;
this.next = null;
}
public void display() {
if (this.next != null) {
System.out.print(data + "-->");
} else {
System.out.print(data);
}
}
@Override
public String toString() {
return "Node [data=" + data + "]";
}
}
单链表的基本操作
最新推荐文章于 2020-11-05 11:56:30 发布