线性表(一)

为了学习好数据结构,准备把书上的算法都亲自敲一遍,每天都要敲一些,是对自己的承诺吧。

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;
			}
		}
	}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值