头歌JAVA数据结构答案
一、Java数据结构-循环链表的设计与实现
第1关 单循环链表的实现—链表的添加、遍历
package step1;
/**
* Created by sykus on 2018/1/15.
*/
public class MyCircleLinkedList {
private Node head;//头结点, 不存数据
private Node tail;//尾结点, 指向链表的最后一个节点
private int size;
public MyCircleLinkedList() {
head = new Node(Integer.MIN_VALUE, null);
head.next = head;
tail = head;
size = 0;
}
/**
* 添加到链表尾部
*
* @param item
*/
public void add(int item) {
/********** Begin *********/
Node node = new Node(item, tail.next);
tail.next = node;
tail = node;
++size;
/********** End *********/
}
/**
* 遍历链表并输出元素
*/
public void output() {
/********** Begin *********/
Node p = head;
while (p.next != head) {
p = p.next;
System.out.println(p.item);
}
/********** End *********/
}
public boolean isEmpty() {
return head.next == head;
}
public int size() {
return size;
}
//结点内部类
private static class Node {
int item;
Node next;
Node(int item, Node next) {
this.item = item;
this.next = next;
}
}
}
第2关 单循环链表的实现—链表的删除
package step2;
/**
* Created by sykus on 2018/1/15.
*/
public class MyCircleLinkedList {
private Node head;//头结点, 不存数据
private Node tail;//尾结点, 指向链表的最后一个节点
private int size;
public MyCircleLinkedList() {
head = new Node(Integer.MIN_VALUE, null);
head.next = head;
tail = head;
size = 0;
}
/**
* 添加到链表尾部
*
* @param item
*/
public void add(int item) {
Node node = new Node(item, tail.next);
tail.next = node;
tail = node;
++size;
}
/**
* 遍历链表并输出元素
*/
public void output() {
Node p = head;
while (p.next != head) {
p = p.next;
System.out.println(p.item);
}
}
/**
* 删除从头结点开始的第index个结点
* index从0开始
*
* @param index
* @return
*/
public int remove(int index) {
checkPosIndex(index);
/********** Begin *********/
Node f = head;
while ((index--) > 0) {
f = f.next;
}
Node del = f.next;
if (del == tail) {//要删除的是尾结点
tail = f;//使tail依然指向末尾结点
}
f.next = del.next;
del.next = null;
int oldVal = del.item;
del = null;
--size;
return oldVal;
/********** End *********/
}
public boolean isEmpty() {
return head.next == head;
}
public int size() {
return size;
}
private void checkPosIndex(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
//结点内部类
private static class Node {
int item;
Node next;
Node(int item, Node next) {
this.item = item;
this.next = next;
}
}
}
第3关 双向循环链表的实现—链表的插入
package step3;
/**
* Created by sykus on 2018/1/15.
*/
public class MyDoubleLinkedList {
private Node head;//头结点
private Node tail;//指向链表的尾结点
private int size;
public MyDoubleLinkedList() {
head = new Node(null, Integer.MIN_VALUE, null);
head.next = head.prev = head;
tail = head;
size = 0;
}
/**
* 添加元素到表尾
*
* @param item
*/
public void add(int item) {
/********** Begin *********/
Node newNode = new Node(null, item, null);
tail.next = newNode;
newNode.prev = tail;
newNode.next = head;
head.prev = newNode;
tail = newNode;
++size;
/********** End *********/
}
/**
* 打印双向链表
*
* @param flag true从左向右顺序打印, false从右向左顺序打印
*/
public void printList(boolean flag) {
Node f = head;
if (flag) {//向右
while (f.next != head) {
f = f.next;
System.out.print(f.item + " ");
}
} else {//向左
while (f.prev != head) {
f = f.prev;
System.out.print(f.item + " ");
}
}
}
public int size() {
return size;
}
//结点内部类
private static class Node {
int item;
Node next;//直接后继引用
Node prev;//直接前驱引用
Node(Node prev, int item, Node next) {
this.prev = prev;
this.item = item;
this.next = next;
}
}
}
第4关:双向循环链表的实现—链表的删除
package step4;
/**
* Created by sykus on 2018/1/15.
*/
public class MyDoubleLinkedList {
private Node head;//头结点
private Node tail;//指向链表的尾结点
private int size;
public MyDoubleLinkedList() {
head = new Node(null, Integer.MIN_VALUE, null);
head.next = head.prev = head;
tail = head;
size = 0;
}
/**
* 添加元素到表尾
*
* @param item
*/
public void add(int item) {
Node newNode = new Node(null, item, null);
tail.next = newNode;
newNode.prev = tail;
newNode.next = head;
head.prev = newNode;
tail = newNode;
++size;
}
/**
* 删除指定位置index出的结点,并返回其值
*
* @param index
* @return
*/
public int remove(int index) {
checkPosIndex(index);//
/********** Begin *********/
Node p = head.next;
while ((index--) > 0) {
p = p.next;
}
if (p == tail) {
tail = p.prev;
}
p.prev.next = p.next;
p.next.prev = p.prev;
int val = p.item;
p = null;
--size;
return val;
/********** End *********/
}
/**
* 打印双向链表
*
* @param flag true从左向右顺序打印, false从右向左顺序打印
*/
public void printList(boolean flag) {
Node f = head;
if (flag) {//向右
while (f.next != head) {
f = f.next;
System.out.print(f.item + " ");
}
} else {//向左
while (f.prev != head) {
f = f.prev;
System.out.print(f.item + " ");
}
}
}
public int size() {
return size;
}
private void checkPosIndex(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
//结点内部类
private static class Node {
int item;
Node next;//直接后继引用
Node prev;//直接前驱引用
Node(Node prev, int item, Node next) {
this.prev = prev;
this.item = item;
this.next = next;
}
}
}
二、Java数据结构-线性表的设计与实现
第1关:顺序表的实现之增删功能
package step1;
/**
* Created by zengpeng on 2017/12/25.
*/
public class MyArrayList {
private int[] elements;//元素
private int size;//List中当前的元素个数
public MyArrayList() {
this(1);//List默认大小为1
}
/**
* 按指定大小capacity构造List
*
* @param capacity List初始化时的大小
*/
public MyArrayList(int capacity) {
elements = new int[capacity];
size = 0;
}
/**
* 返回List中元素的个数
*
* @return
*/
public int size() {
return size;
}
/**
* 添加一个元素到末尾
*
* @param item
*/
public void Add(int item) {
int len = elements.length;
if (size == len - 1) {
resize(2 * len);
}
/********** Begin *********/
elements[size++] = item;
/********** End *********/
}
/**
* 添加一个元素到指定位置index
*
* @param index
* @param item
*/
public void Add(int index, int item) {
validateRangeForAdd(index);
int len = elements.length;
if (size == len - 1) {
resize(2 * len);
}
/********** Begin *********/
for (int i = size; i > index; i--) {
elements[i] = elements[i - 1];
}
elements[index] = item;
size++;
/********** End *********/
}
/**
* 删除指定位置index的元素,并返回被删除的元素
*
* @param index
* @return
*/
public int remove(int index) {
validateRange(index);
/********** Begin *********/
int oldVal=elements[index];
for (int i = index; i < size - 1; i++) {
elements[i] = elements[i + 1];
}
--size;
return oldVal;
/********** End *********/
}
/**
* 校验索引范围
*
* @param index
*/
private void validateRange(int index) {
if (index >= size || index < 0) {
throw new ArrayIndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size);
}
}
/**
* 校验索引范围
*
* @param index
*/
private void validateRangeForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size);
}
/**
* 动态扩展数组大小
*
* @param capacity
*/
private void resize(int capacity) {
assert capacity > size;
int[] tmp = new int[capacity];
for (int i = 0; i < size; i++) {
tmp[i] = elements[i];
}
elements = tmp;
}
}
第2关: 顺序表的实现之查询功能
package step2;
/**
* Cre