为了学习好数据结构,准备把书上的算法都亲自敲一遍,每天都要敲一些,是对自己的承诺吧。
1:已知一个线性表,其中的元素递增有序排列,设计一个算法,插入一个元素x(int型);保证该顺序表依然递增有序排列,这里,假设每次都能够插入成功:
解答:线性表分为两种,数组和链表;这道题,其实就是插入排序的一部分逻辑。
package linetable;
public class InsertElement {
public static void main(String[] args) {
int[] array = new int[] { 1, 3, 5, 7, 9 };
insertElement(array, 10);
System.out.println("\n");
Node first = new Node(1);
first.setNextNode(new Node(3).setNextNode(new Node(5).setNextNode(new Node(7).setNextNode(new Node(9)))));
insertElement(first, 4);
while (first != null) {
System.out.print(first.element + " ");
first = first.nextNode;
}
}
/**
*
* @param root
*/
public static void insertElement(Node root, int index) {
while (null != root.nextNode && root.nextNode.element < index) {
root = root.nextNode;
}
if (null == root.nextNode) {
root.nextNode = new Node(index);
} else {
Node newNode = new Node(index);
newNode.nextNode = root.nextNode;
root.nextNode = newNode;
}
}
/**
*
* @param array
* @param index
*/
public static void insertElement(int[] array, int index) {
int length = array.length;
int[] newArray = new int[length + 1];
int i;
for (i = 0; i < array.length; i++) {
newArray[i] = array[i];
// 如果遇到一个大的数字
if (array[i] > index) {
for (int j = i; j < array.length; j++) {
newArray[i + 1] = array[i];
}
newArray[i] = index;
break;
}
}
if (i == array.length) {
newArray[i] = index;
}
for (int ele : newArray) {
System.out.print(ele + " ");
}
}
}
class Node {
public int element;
public Node nextNode;
public int getElement() {
return element;
}
public Node setElement(int element) {
this.element = element;
return this;
}
public Node getNextNode() {
return nextNode;
}
public Node setNextNode(Node nextNode) {
this.nextNode = nextNode;
return this;
}
public Node(int element) {
super();
this.element = element;
}
}
2:单链表的头插法和尾插法:
package linetable;
public class LinkedListOperation {
public static void main(String[] args) {
int[] array = new int[] { 2, 3, 4, 5, 6 };
// 头插法建立链表
Node first = new Node(1);
insertAtHead(first, array);
while (first != null) {
System.out.print(first.element + " ");
first = first.nextNode;
}
// 尾部插法建立链表
Node second = new Node(1);
insertAtTail(second, array);
while (second != null) {
System.out.print(second.element + " ");
second = second.nextNode;
}
}
public static void insertAtHead(Node first, int[] array) {
for (int i = 0; i < array.length; i++) {
Node newNode = new Node(array[i]);
newNode.nextNode = first.nextNode;
first.nextNode = newNode;
}
}
public static void insertAtTail(Node first, int[] array) {
for (int i = 0; i < array.length; i++) {
first.nextNode = new Node(array[i]);
first = first.nextNode;
}
}
}
3:给定数组,每个元素左移P个位置,0<P<元素个数。
package linetable;
public class ArrayReverse {
public static void main(String[] args) {
int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
firstReverse(array, 4);
for (int ele : array)
System.out.print(ele + " ");
}
public static void firstReverse(int[] array, int distance) {
reverse(array, 0, distance - 1);
reverse(array, distance, array.length - 1);
reverse(array, 0, array.length - 1);
}
public static void reverse(int[] array, int begin, int end) {
int i = begin;
int j = end;
for (; i < j; i++, j--) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
4:双向链表的头插法和尾插法;这里使用有头结点的双向链表。
package linetable;
public class DoubleLinkedListWithHead {
public static void main(String[] args) {
int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
DoubleNode head = new DoubleNode(null, null, null);
// 头插法建立双向链表
insertAtHead(head, array);
while (head.next != null) {
System.out.print(head.next.value + " ");
head = head.next;
}
DoubleNode newHead = new DoubleNode(null, null, null);
insertAtTail(newHead,array);
while (newHead.next != null) {
System.out.print(newHead.next.value + " ");
newHead = newHead.next;
}
}
public static void insertAtHead(DoubleNode head, int[] array) {
for (int ele : array) {
DoubleNode newNode = new DoubleNode(null, null, ele);
newNode.next = head.next;
newNode.prior = head;
head.next = newNode;
}
}
public static void insertAtTail(DoubleNode head, int[] array) {
for (int ele : array) {
DoubleNode newNode = new DoubleNode(null, null, ele);
head.next = newNode;
newNode.prior = head;
head = head.next;
}
}
}
4:两个集合,求取差集合,比如a={1,2,3,4,5},b={2,3,4,6},则结果a-b={1,5}。
package linetable;
public class DifferenceSet {
public static void main(String[] args) {
Node aHead = new Node(null);
Node a = new Node(1);
aHead.nextNode = a;
a.setNextNode(new Node(2).setNextNode(new Node(3).setNextNode(new Node(5).setNextNode(new Node(6)))));
Node bHead = new Node(null);
Node b = new Node(1);
bHead.nextNode = b;
b.setNextNode(new Node(3).setNextNode(new Node(4).setNextNode(new Node(7))));
// 接下来计算a-b
differSet(aHead, bHead);
while(aHead.hasNext()) {
System.out.println(aHead.nextNode.element + " ");
aHead = aHead.nextNode;
}
}
public static void differSet(Node a, Node b) {
// 以a为基准
while (a.hasNext() && b.hasNext()) {
if (b.nextNode.element == a.nextNode.element) {
// 这时候从a中清除该元素
a.nextNode = a.nextNode.nextNode;
}
if (b.nextNode.element < a.nextNode.element) {
b = b.nextNode;
}
if (b.nextNode.element > a.nextNode.element) {
a = a.nextNode;
}
}
}
}
6:单链表元素的逆序输出
解答:带头结点的单链表,使用递归输出:
package linetable;
public class ReversePrint {
public static void main(String[] args) {
Node head = new Node(null);
int[] array = new int[] { 1, 2, 3, 4, 5, 6 };
LinkedListOperation.insertAtTail(head, array);
reversePrint(head);
}
public static void reversePrint(Node head) {
if (null != head.nextNode) {
reversePrint(head.nextNode);
}
if (null != head.element)
System.out.print(head.element + " ");
}
}
7:找到单链表中倒数第K个元素
package linetable;
public class FindLastKElement {
public static void main(String[] args) {
Node aHead = new Node(null);
LinkedListOperation.insertAtTail(aHead, new int[] { 1, 2, 3, 4, 5, 6 });
findLastKElement(aHead, 4);
}
/**
* @description 找到倒数第K个元素
* @param aHead
* @param k
* @return
*/
public static int findLastKElement(Node aHead, int k) {
Node p1 = aHead.nextNode;
Node p = aHead;
int i = 1;
while(p1 != null) {
p1 =p1.nextNode;
i++;
if(i> k) {
p = p.nextNode;
}
}
if(p == aHead)
return 0;
else {
System.out.println(p.element);
return p.element;
}
}
}
8:单调非递减线性表,去除其中重复元素:
先来个数组版本的:
package linetable;
public class DinstinctArray {
public static void main(String[] args) {
int[] array = new int[] { 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 8 };
distinctArray(array);
}
public static void distinctArray(int[] array) {
int j = 1;
for (int i = 0; i < array.length - 1; i++) {
if (array[i + 1] != array[i]) {
array[j++] = array[i + 1];
}
}
for (int i = 0; i < j; i++) {
System.out.print(array[i] + " ");
}
}
}
再来个带头结点单链表版本的:
package linetable;
public class DistinctLinkedList {
public static void main(String[] args) {
Node node = new Node(null);
int[] array = new int[] { 1, 2, 2, 3, 3, 4, 5, 6, 6, 6, 6, 7, 8, 9 };
// 尾插法建立单链表,带头结点
LinkedListOperation.insertAtTail(node, array);
distinctLinkedList(node);
while (node.hasNext()) {
System.out.print(node.nextNode.element + " ");
node = node.nextNode;
}
}
public static void distinctLinkedList(Node head) {
while (head.hasNext()) {
if (head.nextNode.element == head.element) {
head.nextNode = head.nextNode.nextNode;
} else {
head = head.nextNode;
}
}
}
}