Java学习日记(11-20天,线性数据结构)

学习地址

11.顺序表(一)

顺序表:通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表。
顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
比如:tempArray = { 21,511,1129,1226 }就是一个顺序表。
My tempFirstList = new My(tempArray)表示生成一个新对象,并将顺序表传入。

public My(int[] paraArray) {
	data = new int[MAX_LENGTH];
	length = paraArray.length;

	for (int i = 0; i < paraArray.length; i++) {
		data[i] = paraArray[i];
	}
}

在public String toString()中,重写了toString()的方法,在输出对象里的数据时,可以调用toString()函数,或者直接使用 tempFirstList,由于是用另一个字符串与其相加,,系统会自动调用 tempFirstList.toString():

System.out.println("Initialized, the list is: " + tempFirstList.toString());
System.out.println("Again, the list is: " + tempFirstList);

完整代码:

package xjx;

public class My {
	public static void main(String args[]) {
		int[] tempArray = { 1, 4, 6, 9 };
		My tempFirstList = new My(tempArray);
		System.out.println("Initialized, the list is: " + tempFirstList.toString());
		System.out.println("Again, the list is: " + tempFirstList);
		tempFirstList.reset();
		System.out.println("After reset, the list is: " + tempFirstList);
	}

	public static final int MAX_LENGTH = 10;
	int length;
	int[] data;

	/**
	 *********************
	 * Construct an empty sequential list.
	 *********************
	 */
	public My() {
		length = 0;
		data = new int[MAX_LENGTH];
	}

	/**
	 *********************
	 * Construct a sequential list using an array.
	 * 
	 * @param paraArray
	 *            The given array. Its length should not exceed MAX_LENGTH. For
	 *            simplicity now we do not check it.
	 *********************
	 */
	public My(int[] paraArray) {
		data = new int[MAX_LENGTH];
		length = paraArray.length;

		for (int i = 0; i < paraArray.length; i++) {
			data[i] = paraArray[i];
		}
	}

	/**
	 *********************
	 * Overrides the method claimed in Object, the superclass of any class.
	 *********************
	 */
	public String toString() {
		String resultString = "";

		if (length == 0) {
			return "empty";
		}

		for (int i = 0; i < length; i++) {
			if(i==length-1)resultString += data[length - 1];
			else resultString += data[i] + ", ";
		}

		return resultString;
	}

	/**
	 *********************
	 * Reset to empty.
	 *********************
	 */
	public void reset() {
		length = 0;
	}
}

运行结果:
在这里插入图片描述

12.顺序表(二)

今天的代码在昨天的基础上添加对顺序表的查找,插入,删除功能。
1.查找:查找指定元素paraValue,如果不存在返回-1

public int locate(int paraValue) {
   	int tempPosition = -1;
   	for (int i = 0; i < length; i++) {
   		if (data[i] == paraValue) {
   			tempPosition = i;
   			break;
   		}
   	}
   	return tempPosition;
}

2.插入:在指定位置插入元素,如果顺序表已满或者插入的位置不在有效范围内就不能插入,然后将从指定位置到顺序表末尾的元素以此往后移一位,再把待插入元素赋值给指定位置,顺序表长度加一

public boolean insert(int paraPosition, int paraValue) {
   	if (length == MAX_LENGTH) {
   		System.out.println("顺序表已满.");
   		return false;
   	}
   	if ((paraPosition < 0) || (paraPosition > length)) {
   		System.out.println("没有位置" + paraPosition);
   		return false;
   	}
   	for (int i = length; i > paraPosition; i--) {
   		data[i] = data[i - 1];
   	}
   	data[paraPosition] = paraValue;
   	length++;
   	return true;
}

3.删除:删除指定位置的元素,如果位置不在有效范围内则不能删除,然后将从指定位置到顺序表末尾的元素向前移一位,顺序表长度减一

public boolean delete(int paraPosition) {
   	if ((paraPosition < 0) || (paraPosition >= length)) {
   		System.out.println("没有位置" + paraPosition);
   		return false;
   	}
   	for (int i = paraPosition; i < length - 1; i++) {
   		data[i] = data[i + 1];
   	}
   	length--;
   	return true;
}

完整代码:

package xjx;

public class My {
	public static void main(String args[]) {
		int[] tempArray = { 5,11,29,66 };
		My tempFirstList = new My(tempArray);
		System.out.println("顺序表: " + tempFirstList.toString());
		
		int tempValue = 11;
		int tempPosition = tempFirstList.locate(tempValue);
		System.out.println("数字"+ tempValue + "在位置:" + tempPosition);
		tempValue = 29;
		tempPosition = tempFirstList.locate(tempValue);
		System.out.println("数字"+ tempValue + "在位置:" + tempPosition);
		
		tempPosition = 2;
		tempValue = 8;
		tempFirstList.insert(tempPosition, tempValue);
		System.out.println("插入数字" + tempValue + "到位置:" + tempPosition
				+ ", 现在的顺序表: " + tempFirstList);
		
		tempPosition = 8;
		tempValue = 10;
		tempFirstList.insert(tempPosition, tempValue);
		System.out.println("插入数字" + tempValue + "到位置:" + tempPosition
				+ ", 现在的顺序表: " + tempFirstList);
		
		tempPosition = 3;
		tempFirstList.delete(tempPosition);
		System.out.println("删除位置" + tempPosition + "的数字, 现在的顺序表: "
				+ tempFirstList);
		
		for(int i = 0; i < 8; i ++) {
			tempFirstList.insert(i, i);
			System.out.println("插入数字" + i + "到位置:" + i
					+ ", 顺序表: " + tempFirstList);
		}
		
		tempFirstList.reset();
		System.out.println("清空后的顺序表: " + tempFirstList);
	}

	public static final int MAX_LENGTH = 10;
	int length;
	int[] data;

	/**
	 *********************
	 * Construct an empty sequential list.
	 *********************
	 */
	public My() {
		length = 0;
		data = new int[MAX_LENGTH];
	}

	/**
	 *********************
	 * Construct a sequential list using an array.
	 * 
	 * @param paraArray
	 *            The given array. Its length should not exceed MAX_LENGTH. For
	 *            simplicity now we do not check it.
	 *********************
	 */
	public My(int[] paraArray) {
		data = new int[MAX_LENGTH];
		length = paraArray.length;

		for (int i = 0; i < paraArray.length; i++) {
			data[i] = paraArray[i];
		}
	}

	/**
	 *********************
	 * Overrides the method claimed in Object, the superclass of any class.
	 *********************
	 */
	public String toString() {
		String resultString = "";

		if (length == 0) {
			return "empty";
		}

		for (int i = 0; i < length; i++) {
			if(i==length-1)resultString += data[length - 1];
			else resultString += data[i] + ", ";
		}

		return resultString;
	}

	/**
	 *********************
	 * Reset to empty.
	 *********************
	 */
	public void reset() {
		length = 0;
	}
	/**
    *********************
    * Locate the given value. If it appears in multiple positions, simply
    * return the first one.
    * 
    * @param paraValue
    *            The given value.
    * @return The position. -1 for not found.
    *********************
    */
	public int locate(int paraValue) {
	   	int tempPosition = -1;
	   	for (int i = 0; i < length; i++) {
	   		if (data[i] == paraValue) {
	   			tempPosition = i;
	   			break;
	   		}
	   	}
	   	return tempPosition;
	}

   /**
    *********************
    * Insert a value to a position. If the list is already full, do nothing.
    * 
    * @param paraPosition
    *            The given position.
    * @param paraValue
    *            The given value.
    * @return Success or not.
    *********************
    */
	public boolean insert(int paraPosition, int paraValue) {
	   	if (length == MAX_LENGTH) {
	   		System.out.println("顺序表已满.");
	   		return false;
	   	}
	   	if ((paraPosition < 0) || (paraPosition > length)) {
	   		System.out.println("没有位置" + paraPosition);
	   		return false;
	   	}
	   	for (int i = length; i > paraPosition; i--) {
	   		data[i] = data[i - 1];
	   	}
	   	data[paraPosition] = paraValue;
	   	length++;
	   	return true;
	}

   /**
    *********************
    * Delete a value at a position.
    * 
    * @param paraPosition
    *            The given position.
    * @return Success or not.
    *********************
    */
	public boolean delete(int paraPosition) {
	   	if ((paraPosition < 0) || (paraPosition >= length)) {
	   		System.out.println("没有位置" + paraPosition);
	   		return false;
	   	}
	   	for (int i = paraPosition; i < length - 1; i++) {
	   		data[i] = data[i + 1];
	   	}
	   	length--;
	   	return true;
	}
}

进行查找,插入与删除操作,运行结果:
在这里插入图片描述

13.链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表由一系列结点组成,一般情况下每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

链表与顺序表相比(假设长度为N):
①插入与删除,链表可以通过改变指针域,直接插入和删除某一个元素,时间复杂度为O(1),但是顺序表的插入删除操作需要移动大量元素,时间复杂度为O(N);
②查找元素,顺序表中可以通过数组下标直接查找元素,时间复杂度为O(1),但链表需要从头结点开始依此查找,时间复杂度为O(N)。

为节点建立一个类Node,结点内有data数据域和next下一个结点指针域:

class Node {
	int data;
	Node next;
	public Node(int paraValue) {
		data = paraValue;
		next = null;
	}
}
Node header;

初始化链表,建立头结点:
header = new Node(0);
header.next = null;

查找元素:从头结点的下一个元素(即链表第一个元素)开始查找,当还没到链表末尾,如果结点的数据域与查找元素相等,跳出循环,返回位置。

public int locate(int paraValue) {
	int tempPosition = -1;
	Node tempNode = header.next;
	int tempCurrentPosition = 0;
	while (tempNode != null) {
		if (tempNode.data == paraValue) {
			tempPosition = tempCurrentPosition;
			break;
		}
		tempNode = tempNode.next;
		tempCurrentPosition++;
	}
	return tempPosition;
}

插入元素:传入要插入的位置以及数据,从头结点开始查找插入位置,找到后将数据存到新结点,让新结点的next指针域指向当前位置结点的next指针域,再将当前位置结点的next指针域指向新结点,便插入成功。

public boolean insert(int paraPosition, int paraValue) {
	Node tempNode = header;
	Node tempNewNode;
	for (int i = 0; i < paraPosition; i++) {
		if (tempNode == null) {
			System.out.println("插入位置" + paraPosition + "是非法的");
			return false;
		}
		tempNode = tempNode.next;
	}
	tempNewNode = new Node(paraValue);
	tempNewNode.next = tempNode.next;
	tempNode.next = tempNewNode;
	return true;
}

在测试插入代码时发现,假如链表有5个结点,在0-5位置插入时都可以,但是当在位置6插入时报错Exception in thread “main” java.lang.NullPointerException,按照代码所写逻辑应该返回“插入位置不合法”的错误处理:
在这里插入图片描述
错误为空指针异常,因为在循环到位置5时,当前结点是有数据的,所以不会进if错误判断,然后执行后面的语句,但是next指针域已经为空,所以会出现空指针异常错误,将语句 tempNode == null 改为 tempNode.next == null 后可以正常运行。

删除元素:当链表中只有头结点时,链表为空,无法删除元素;如果除了头结点还有其他结点,从头结点开始查找要删除的指定位置的前一个位置,找到后将该结点的next指针域指向要删除的指定位置的next指针域。

public boolean delete(int paraPosition) {
	if (header.next == null) {
		System.out.println("不能删除空链表.");
		return false;
	}
	Node tempNode = header;
	for (int i = 0; i < paraPosition; i++) {
		if (tempNode.next == null) {
			System.out.println("删除位置" + paraPosition + "是非法的");
			return false;
		}
		tempNode = tempNode.next;
	}
	tempNode.next = tempNode.next.next;
	return true;
}

与插入报了一样的空指针异常错误:
在这里插入图片描述
将tempNode.next == null改为tempNode.next.next == null即可成功运行。

完整代码:

package xjx;
import java.util.Arrays;

public class My {
	public static void main(String args[]) {
		My tempFirstList = new My();
		System.out.println("初始化的链表: " + tempFirstList.toString());
		System.out.println("/插入/");
		for(int i = 0; i < 5; i ++) {
			tempFirstList.insert(0, i);
		}
		System.out.println("插入元素后的链表: " + tempFirstList.toString());
		tempFirstList.insert(6, 11);
		System.out.println("插入元素11到位置6后的链表: " + tempFirstList.toString());
		System.out.println("/查找/");
		int poi=tempFirstList.locate(3);
		System.out.println("查找元素3的下标: " + poi);
		System.out.println("/删除/");
		tempFirstList.delete(2);
		System.out.println("删除位置2的元素后的链表: " + tempFirstList.toString());
		tempFirstList.delete(4);
		System.out.println("删除位置4的元素后的链表: " + tempFirstList.toString());
		
		for(int i = 0; i < 5; i ++) {
			tempFirstList.delete(0);
			System.out.println("循环删除位置0的元素,链表: " + tempFirstList.toString());
		}
	}
	
	class Node {
		int data;
		Node next;
		public Node(int paraValue) {
			data = paraValue;
			next = null;
		}
	}
	Node header;

	public My() {
		header = new Node(0);
		header.next = null;
	}

	public String toString() {
		String resultString = "";
		if (header.next == null) {
			return "empty";
		}
		Node tempNode = header.next;
		while (tempNode != null) {
			resultString += tempNode.data + ", ";
			tempNode = tempNode.next;
		}
		return resultString;
	}

	public void reset() {
		header.next = null;
	}

	public int locate(int paraValue) {
		int tempPosition = -1;
		Node tempNode = header.next;
		int tempCurrentPosition = 0;
		while (tempNode != null) {
			if (tempNode.data == paraValue) {
				tempPosition = tempCurrentPosition;
				break;
			}
			tempNode = tempNode.next;
			tempCurrentPosition++;
		}
		return tempPosition;
	}

	public boolean insert(int paraPosition, int paraValue) {
		Node tempNode = header;
		Node tempNewNode;

		for (int i = 0; i < paraPosition; i++) {
			if (tempNode.next == null) {
				System.out.println("插入位置" + paraPosition + "是非法的");
				return false;
			}
			tempNode = tempNode.next;
		}

		tempNewNode = new Node(paraValue);
		tempNewNode.next = tempNode.next;
		tempNode.next = tempNewNode;
		return true;
	}

	public boolean delete(int paraPosition) {
		if (header.next == null) {
			System.out.println("不能删除空链表.");
			return false;
		}
		
		Node tempNode = header;
		for (int i = 0; i < paraPosition; i++) {
			if (tempNode.next.next == null) {
				System.out.println("删除位置" + paraPosition + "是非法的");
				return false;
			}
			tempNode = tempNode.next;
		}
		
		tempNode.next = tempNode.next.next;
		return true;
	}
}

正确运行结果:
在这里插入图片描述

14.栈

栈是一种运算受限的线性表,限定仅在表尾进行插入和删除操作。一端被称为栈顶,相对地,另一端称为栈底。
定义一个data数组,用数组模拟栈的操作:

public My() {
	depth = 0;
	data = new char[MAX_DEPTH];
}

入栈:向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;
将要入栈元素加入栈顶,深度加一,如果栈深度已经是最大深度,则栈满,拒绝入栈。

public boolean push(char paraChar) {
	if (depth == MAX_DEPTH) {
		System.out.println("栈已满.");
		return false;
	}
	data[depth] = paraChar;
	depth++;
	return true;
}

出栈:从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
获取栈顶元素,深度减一,如果栈深度为零,则栈空,无法出栈。

public char pop() {
	if (depth == 0) {
		System.out.println("栈空.");
		return '\0';
	}
	char resultChar = data[depth - 1];
	depth--;
	return resultChar;
}

完整代码:

package xjx;

public class My {
	public static void main(String args[]) {
		My tempStack = new My();
		for (char ch = 'a'; ch < 'e'; ch++) {
			tempStack.push(ch);
			System.out.println(ch +"入栈 ");
			System.out.println("当前栈: " + tempStack);
		}
		char tempChar;
		for (int i = 0; i < 2; i++) {
			tempChar = tempStack.pop();
			System.out.println("将:"+tempChar +"出栈 ");
			System.out.println("当前栈: " + tempStack);
		}
	}
	public static final int MAX_DEPTH = 10;
	int depth;
	char[] data;

	public My() {
		depth = 0;
		data = new char[MAX_DEPTH];
	}

	public String toString() {
		String resultString = "";
		for (int i = 0; i < depth; i++) {
			resultString += data[i];
		}
		return resultString;
	}

	public boolean push(char paraChar) {
		if (depth == MAX_DEPTH) {
			System.out.println("栈已满.");
			return false;
		}
		data[depth] = paraChar;
		depth++;
		return true;
	}

	public char pop() {
		if (depth == 0) {
			System.out.println("栈空.");
			return '\0';
		}
		char resultChar = data[depth - 1];
		depth--;
		return resultChar;
	}
}

入栈和出栈结果:
在这里插入图片描述

15.栈的应用(括号匹配)

任务描述: 检查一个字符串的括号是否匹配. 所谓匹配, 是指每个左括号有相应的一个右括号与之对应, 且左括号不可以出现在右括号右边. 可以修改测试字符串, 检查不同情况下的运行.
1、仅在栈的代码基础上增加了一个 bracketMatching 方法, 以及 main 中的相应调试语句.
2、一旦发现不匹配, 直接返回false.
3、引用Scanner输入字符串来判断.

在bracketMatching 方法中,遍历字符串,当遇到“{”,“[”,“(”时压栈,当遇到“}”时判断栈顶是否为“{”,如果不是则不匹配,直接返回false。如果匹配则栈顶出栈,继续遍历,遇到“]”和“)”时与{}判断方法一样。

引用Scanner输入五个字符串:

int t=5;
while(t!=0) {
	boolean tempMatch;
	Scanner sc = new Scanner(System.in);
	String tempExpression = null;
    System.out.print("输入字符串:");
    tempExpression = sc.nextLine();
	tempMatch = bracketMatching(tempExpression);
	System.out.println("括号是否匹配? " + tempMatch);	
	t--;
}

bracketMatching 方法代码:

public static boolean bracketMatching(String paraString) {
	My tempStack = new My();
	tempStack.push('#');
	char tempChar, tempPopedChar;
	for (int i = 0; i < paraString.length(); i++) {
		tempChar = paraString.charAt(i);
		switch (tempChar) {
		case '(':
		case '[':
		case '{':
			tempStack.push(tempChar);
			break;
		case ')':
			tempPopedChar = tempStack.Getpop();
			if (tempPopedChar != '(') {
				return false;
			}
			tempStack.pop();
			break;
		case ']':
			tempPopedChar = tempStack.Getpop();
			if (tempPopedChar != '[') {
				return false;
			}
			tempStack.pop();
			break;
		case '}':
			tempPopedChar = tempStack.Getpop();
			if (tempPopedChar != '{') {
				return false;
			}
			tempStack.pop();
			break;
		default:
		}
	}

	tempPopedChar = tempStack.Getpop();
	if (tempPopedChar != '#') {
		return false;
	}
	tempStack.pop();
	return true;
}

运行结果:
在这里插入图片描述

16.递归

递归就是在运行程序的过程中调用自己,每递归一次就压栈一次,直到达到递归结束条件时,层层出栈。
构成递归需要具备的条件:
1.子问题必须与原始问题为同样的事件,且更为简单;
2.不能无限制地调用本身,必须有个出口,化简为非递归状况处理。

加法递归:
例如从传参paraN=5,调用sumToN(4),然后依此往前调用自身函数,压栈,直到paraN<=0,返回零的值,再依此往后加上当前函数的参数:0+1+2+3+4+5直到全部出栈,返回结果15。

public static int sumToN(int paraN) {
	if (paraN <= 0) {
		return 0;
	}
	return sumToN(paraN - 1) + paraN;
}

斐波拉契数列:定义F(0)=0,F(1)=1,F(n)=F(n - 1)+F(n - 2)

public static int fibonacci(int paraN) {
	if (paraN <= 0) {
		return 0;
	} if (paraN <= 1) {
		return 1;
	}
	return fibonacci(paraN - 1) + fibonacci(paraN - 2);
}

完整代码:

package xjx;

public class My {
	public static void main(String args[]) {
		int tempValue = 5;
		System.out.println("0 sum to " + tempValue + " = " + sumToN(tempValue));
		tempValue = -1;
		System.out.println("0 sum to " + tempValue + " = " + sumToN(tempValue));
		
		for(int i = 0; i < 10; i ++) {
			System.out.println("Fibonacci " + i + ": " + fibonacci(i));
		}
	}
	
	public static int sumToN(int paraN) {
		if (paraN <= 0) {
			return 0;
		}

		return sumToN(paraN - 1) + paraN;
	}

	public static int fibonacci(int paraN) {
		if (paraN <= 0) {
			return 0;
		} if (paraN <= 1) {
			return 1;
		}
		return fibonacci(paraN - 1) + fibonacci(paraN - 2);
	}
}

运行结果:
1.返回0加到5的结果
2.返回0加到-1的结果
3.从0到9的斐波拉契数列值
在这里插入图片描述

17.链队列

队列:是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。
进行插入操作的端称为队尾,进行删除操作的端称为队头。

重写Node类,并定义头结点和尾结点,一个结点有数据域和next指针域:

class Node {
	int data;
	Node next;
	public Node(int paraValue) {
		data = paraValue;
		next = null;
	}
}
Node header;
Node tail;

初始化队列的头结点,使尾指针指向头结点:
header = new Node(-1);
header.next = null;
tail = header;

入队:建立新结点,在队尾加入,使尾结点的next域指向新结点,并更新尾指针指向新的结点。

public void enqueue(int paraValue) {
	Node tempNode = new Node(paraValue);
	tail.next = tempNode;
	tail = tempNode;
}

出队:获取第一个结点的data,并返回,然后删除当前结点,如果队列中只有头结点则返回-1,表示队列空。

public int dequeue() {
	if (header.next == null) {
		System.out.println("队列中没有元素");
		return -1;
	}
	int resultValue = header.next.data;
	header.next = header.next.next;
	return resultValue;
}

完整代码:

package xjx;

public class My {
	public static void main(String args[]) {
		My tempQueue = new My();
		System.out.println("初始队列:" + tempQueue.toString());

		for (int i = 0; i < 5; i++) {
			tempQueue.enqueue(i + 1);
		}
		System.out.println("入队后的队列: " + tempQueue.toString());

		tempQueue.dequeue();
		System.out.println("出队一次,队列:" + tempQueue.toString());

		int tempValue;
		for (int i = 0; i < 5; i++) {
			tempValue = tempQueue.dequeue();
			if(tempValue==-1)break;
			System.out.println("循环出队:" + tempValue + ",新队列:" + tempQueue.toString());
		}
	}
	
	class Node {
		int data;
		Node next;
		public Node(int paraValue) {
			data = paraValue;
			next = null;
		}
	}

	Node header;
	Node tail;

	public My() {
		header = new Node(-1);
		header.next = null;
		tail = header;
	}

	public void enqueue(int paraValue) {
		Node tempNode = new Node(paraValue);
		tail.next = tempNode;
		tail = tempNode;
	}

	public int dequeue() {
		if (header.next == null) {
			System.out.println("队列中没有元素");
			return -1;
		}

		int resultValue = header.next.data;

		header.next = header.next.next;

		return resultValue;
	}

	public String toString() {
		String resultString = "";

		if (header.next == null) {
			return "empty";
		}

		Node tempNode = header.next;
		while (tempNode != null) {
			resultString += tempNode.data + ", ";
			tempNode = tempNode.next;
		}
		return resultString;
	}
}

入队与出队操作的运行截图:
在这里插入图片描述

18.循环队列

循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。
循环队列可以克服“假溢出”问题。
在这里插入图片描述
定义循环队列最大长度为10,定义队列data,头指针head,尾指针tail。

public static final int TOTAL_SPACE = 10;

int[] data;
int head;
int tail;

public My() {
	data = new int[TOTAL_SPACE];
	head = 0;
	tail = 0;
}

入队:在队尾入队,所以修改尾指针tail,将元素加入队尾,下标为尾指针求余最大长度。判断队满的条件为尾指针下一个位置求余最大长度是头指针的位置。

public int enqueue(int paraValue) {
	if ((tail + 1) % TOTAL_SPACE == head) {
		System.out.println("队列已满.");
		return -1;
	}
	data[tail % TOTAL_SPACE] = paraValue;
	tail++;
	return 1;
}

出队:队首出队,获取队列中头指针所指元素,头指针位置向后移动一位。当头指针和尾指针指向同一个位置表示队列中已没有元素。

public int dequeue() {
	if (head == tail) {
		System.out.println("队列中已没有元素");
		return -1;
	}
	int resultValue = data[head];
	head++;
	return resultValue;
}

运行结果:
1.将数字1-5入队;
2.将1出队;
3.将数字10-14入队;
4.将2、3、4出队;
5.将数字100-102入队;
在这里插入图片描述

19.字符串匹配

将字符串赋值给data数组:

public My(String paraString) {
	data = new char[MAX_LENGTH];
	length = paraString.length();
	for (int i = 0; i < length; i++) {
		data[i] = paraString.charAt(i);
	} 
}

字符串匹配:查找第二个字符串在第一个字符串中第一次出现的位置。

public int locate(My paraMy) {
	boolean tempMatch = false;
	for (int i = 0; i < length - paraMy.length + 1; i++) {
		tempMatch = true;
		for (int j = 0; j < paraMy.length; j++) {
			if (data[i + j] != paraMy.data[j]) {
				tempMatch = false;
				break;
			}
		}
		if (tempMatch) {
			return i;
		}
	}
	return -1;
}

剪切字符串:参数为要剪切的字符串的开始位置和要剪切的长度。当要剪切的字符串长度大于总长度返回null

public My substring(int paraStartPosition, int paraLength) {
	if (paraStartPosition + paraLength > length) {
		System.out.println("The bound is exceeded.");
		return null;
	}
	My resultMy = new My();
	resultMy.length = paraLength;
	for (int i = 0; i < paraLength; i++) {
		resultMy.data[i] = data[paraStartPosition + i];
	}
	return resultMy;
}

注意输出引号时需要用到转义符
运行结果:
在这里插入图片描述

20.综合任务2

1、面向对象与面向过程相比, 有哪些优势? 注: 第 1 - 10 天的程序, 就是面向过程的.
面向对象可以在一个类中写很多功能函数,并且可以扩充,容易维护、可读性高,类也可以继承,还可以重写,代码的利用率较高。

2、比较线性表和链表的异同.
线性表和链表都是在逻辑上连续的,但在物理空间内存中线性表是连续的,链表是随机的。

3、分析线性表和链表的优缺点.
如果对列表的插入和删除操作很频繁,就用链表,因为时间复杂度是O(1),线性表是O(n),如果是要频繁的查找列表中的元素,就用线性表,时间复杂度为O(1),链表是O(n)。

4、分析调试程序常见的问题及解决方案.
常见问题有:数组越界、空指针和针对具体题目的一些问题,解决方案就是特判,做异常处理。

5、分析链队列与循环队列的优缺点.
循环队列可以对空间重复利用,避免假溢出的现象,但是一开始就定义了队列的总长度,万一有更多的元素需要入队就不好处理,而链队列在空间上更加灵活,可以增加长度。

6、第 18 天建立的两个队列, 其区别仅在于基础数据不同, 一个是 int, 一个是 char. 按这种思路, 对于不同的基础数据类型, 都需要重写一个类, 这样合理吗? 你想怎么样?
如果每个数据类型都重写一个类就太繁琐了,我觉得可以用模板类,例如class list{},T可以是int、char以及其他的数据类型。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值