第二次博客,基本数据结构(顺序表,链表,栈以及部分相关应用)

2021.12.26

第 11 天: 顺序表

日志:完成了对顺序表的创建,我发现自己还是没有明白对象到底该怎么用,感觉这个和c语言的结构体差不多,但又差很多。。。

将顺序表相关操作全部在这个类中实现,以后创建对象时,对象就可以用相关操作了。

package basic;

public class SequentialList {

	public static final int MAX_LENGTH = 10;// 定义顺序表最大值,是常数
	int length;
	int[] data;

	public SequentialList() {
		length = 0;
		data = new int[MAX_LENGTH];
	}// 无参构造

	public SequentialList(int[] arr) {
		data = new int[MAX_LENGTH];
		for (int i = 0; i < arr.length; i++) {
			data[i] = arr[i];
			length++;
		} // 有参构造
	}

	public void reset() {
		length = 0;
	}

	public String toString() {
		if (length <= 0) {
			return "当前没有元素";
		}
		String resultString = "元素:";
		for (int i = 0; i < length; i++) {
			resultString += data[i] + ",";// String的用法????
		}
		return resultString;
	}

	public static void main(String[] args) {// 对这个顺序表进行测试
		int[] a = { 1, 2, 3, 4 };
		SequentialList SqList = new SequentialList(a);
		System.out.println("当前顺序表长度:" + SqList.length);
		System.out.println("当前所存在的" + SqList.toString());
		SqList.reset();
		System.out.println("当前顺序表长度:" + SqList.length);
		System.out.println("当前所存在的元素:" + SqList.toString());
	}
}

继续:以上实现了顺序表的创建和清除(也就是长度设为0罢了),继续实现在特定位置插入和删除数据。这里的话一旦数据超出了顺序表的范围,就会提醒出错,不会把数据加入数据表。在进行数据删除和添加时,还要关注顺序表为空和为满的情况。(稍后再来继续写。。。。)

更新后代码:增加了顺序表插入,删除,查找元素的基本功能。

搭建了顺序表基本框架,实现功能就很简单了。

package basic;

public class SequentialList {

	public static final int MAX_LENGTH = 10;// 定义顺序表最大值,是常数
	int length;
	int[] data;

	public SequentialList() {
		length = 0;
		data = new int[MAX_LENGTH];
	}// 无参构造

	public SequentialList(int[] arr) {
		data = new int[MAX_LENGTH];
		for (int i = 0; i < arr.length; i++) {
			data[i] = arr[i];
			length++;
		} // 有参构造
	}

	public void reset() {
		length = 0;
		System.out.println("顺序表已清空");
	}

	public String toString() {
		if (length <= 0) {
			return "当前没有元素";
		}
		String resultString = "";
		for (int i = 0; i < length; i++) {
			if (i == 0)
				resultString += data[i];
			else
				resultString += "," + data[i];// String的用法????
		}
		return resultString;
	}

	public void AddElem(int location, int elem) {// 位置 要插入的元素
		if (length == MAX_LENGTH) {
			System.out.println("顺序表已满!");
			return;
		}
		if (location <= 0 || location > length + 1) {
			System.out.println("输入不合法,请重新输入");
			return;
		}
		for (int i = length - 1; i >= location - 1; i--) {
			data[i + 1] = data[i];
		}
		data[location - 1] = elem;
		length++;
		System.out.println("插入成功!");
	}// 向指定位置添加元素

	public int DeleteElem(int location) {
		if (length == 0) {
			System.out.println("顺序表已空,删除失败!");
			return -1;
		}
		if (location <= 0 || location > length) {
			System.out.println("输入不合法,请重新输入");
			return -1;
		}
		for (int i = location - 1; i < length; i++) {
			data[i] = data[i + 1];
		}
		length--;
		return data[location - 1];
	}// 删除指定位置的元素

	public int GetIndex(int num) {
		if (length <= 0) {
			return -1;
		}
		if (num <= 0 || num > length) {
			return -1;
		}
		int flag = 0;// 查找判定
		return data[num - 1];
	}// 获取对应位置的元素

	public static void main(String[] args) {// 对这个顺序表进行测试
		int[] a = { 1, 2, 3, 4 };
		SequentialList SqList = new SequentialList(a);
		System.out.println("当前顺序表长度:" + SqList.length);
		System.out.println("当前所存在的元素:" + SqList.toString());
		SqList.reset();
		System.out.println("当前顺序表长度:" + SqList.length);
		System.out.println("当前所存在的元素:" + SqList.toString());
		SqList.AddElem(1, 18);
		SqList.AddElem(1, 90);
		SqList.AddElem(2, 100);
		System.out.println("当前所存在的元素:" + SqList.toString());
		SqList.reset();
		System.out.println("当前所存在的元素:" + SqList.toString());
		SqList.DeleteElem(1);
		System.out.println("当前所存在的元素:" + SqList.toString());
	}
}
当前顺序表长度:4
当前所存在的元素:1,2,3,4
顺序表已清空
当前顺序表长度:0
当前所存在的元素:当前没有元素
插入成功!
插入成功!
插入成功!
当前所存在的元素:90,100,18
顺序表已清空
当前所存在的元素:当前没有元素
顺序表已空,删除失败!
当前所存在的元素:当前没有元素

基本数据结构顺序表,删除和添加会比较麻烦,不过查找起来却很轻松。

2021.12.27:

继续链表操作:

支持与顺序表相同的操作: 初始化、插入、删除等.
1 为节点建一个类.
2 引用与指针的异同. 前者只能使用; 后者可以支持 p ++ 危险操作.
3 引用数据类型的赋值, 都不会产生新的对象空间.
4 链表与线性表在插入、删除时的不同: 前者不移动元素, 只改变引用 (指针).

终于有时间了,我把接下来的链表基本功能进行了完善,目前有如下功能:

1:头插,尾插数据。指定位置插入数据。

2:遍历链表。获得链表长度。

3:删除指定位置元素。清空链表。

在做的的时候我在想java它有自动回收,那当我清空链表时,将head指向null,不知道回收机制会不会回收掉之后的内容,我下去再看看。

package basic;

//本次含有头结点。
public class LinkedList {
	static Node head = new Node();// 定义头结点,本处头结点供所有方法进行使用,因此加上static

	public void TailAdd(int elem) {
		Node newnode = new Node(elem);
		Node temp = head;
		while (temp.next != null) {
			temp = temp.next;
		} // 遍历搜寻最后一个节点位置
		temp.next = newnode;
//		System.out.println("插入成功!");
		/*
		 * while(temp != null) { temp = temp.next; } temp = newnode;//感觉和c语言有很大不同,等下再看看
		 */

	}// 尾插法插入

	public void HeadAdd(int elem) {
		Node temp = head;
		Node newnode = new Node(elem);
		newnode.next = temp.next;
		temp.next = newnode;
//		System.out.println("插入成功!");
	}// 头插法插入

	public void IndexAdd(int index, int elem) {
		if (index <= 0 || index > ElemNum() + 1) {
			System.out.println("输入不合法,插入失败!");
			return;
		}
		Node pre = head;
		Node cur = head.next;
		Node newnode = new Node(elem);
		for (int i = 1; i <= index - 1; i++) {
			cur = cur.next;
			pre = pre.next;
		}
		pre.next = newnode;
		newnode.next = cur;
		System.out.println("插入成功!");
	}// 指定位置插入

	public void Delete(int index) {
		if (head.next == null) {
			System.out.println("当前链表无元素!");
			return;
		}
		if (index <= 0 || index > ElemNum()) {
			System.out.println("输入不合法,删除失败!");
			return;
		}
		Node pre = head;// 标记删除节点的前一个节点
		Node cur = head.next;// 标记删除节点
		for (int i = 1; i <= index - 1; i++) {
			cur = cur.next;
			pre = pre.next;
		}
		pre.next = cur.next;
		System.out.println("删除了第" + index + "个元素!");
	}// 指定位置删除节点

	public static int ElemNum() {
		int num = 0;
		if (head.next == null) {
			return num;
		}
		Node temp = head.next;
		while (temp != null) {
			num++;
			temp = temp.next;
		}
		return num;
	}

	public void Reverse() {
		if (head.next == null) {
			System.out.println("链表为空!");
			return;
		}
		Node temp = head.next;
		System.out.print("当前元素有:");
		while (temp != null) {
			System.out.print(temp.elem + " ");
			temp = temp.next;
		}
		System.out.println("");
	}// 遍历查询

	public void DeleteAll() {
		head.next = null;
		System.out.println("链表已清空");
	}// 删除所有节点

	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		list.TailAdd(1);
		list.TailAdd(3);
		list.TailAdd(5);
		list.TailAdd(6);
		list.IndexAdd(1, 80);
		list.IndexAdd(2, 99);
		System.out.println("当前元素个数:" + list.ElemNum());
		list.Reverse();
		list.Delete(2);
		list.Reverse();
		list.HeadAdd(9);
		list.HeadAdd(12);
		list.Reverse();
	}// main方法进行链表测试

}

class Node {// 添加节点类,存储数据和指向下一个的引用(这里存储int类型)
	int elem;
	Node next;

	public Node() {// 初始化节点
		elem = 0;
//		next = null;
	}

	public Node(int elem) {
		this.elem = elem;
//		next = null;
	}
}
当前元素个数:6
当前元素有:80 99 1 3 5 6 
删除了第2个元素!
当前元素有:80 1 3 5 6 
当前元素有:12 9 80 1 3 5 6 

链表删除添加元素很轻松,遍历起来就稍微有点麻烦了。基本数据结构,实现难度小。

有时间再来补充接下来的内容吧,哈哈。

2021.12.28


 push 和 pop 均只能在栈顶操作.
 没有循环, 时间复杂度为 O ( 1 )

栈元素先入后出,明白顺序表怎么写的话,这个写起来就很简单了。代码如下:

package basic;

public class Stack {
	//这里我就默认外部输入的数组长度是小于MAX_SIZE了,就不加条件判断了。
	public static final int MAX_SIZE=10;//定义顺序栈容量
	int []data;//栈中数组。
	int length = 0;//当前栈中元素数量。
	public Stack() {
		data = new int[MAX_SIZE];
	}
	
	public Stack(int[] arr) {
		data = new int[arr.length];
		length = arr.length;
		for(int i =0;i<length;i++) {
			data[i] = arr[i];
		}
	}
	
	public void push(int elem) {
		if(length>=MAX_SIZE) {
			System.out.println("当前栈已满,添加失败!");
			return;
		}
		data[length++] = elem;
	}//压栈
	
	public int pop() {
		if(length<=0) {
			System.out.println("当前栈已空,删除失败!");
			return -101010;
		}
		int temp = data[length-1];
		length--;
		return temp;
	}//弹栈
	
	public int ElemNum() {
		return length;
	}//当前栈元素数
	
	public void Reverse() {
		if(length<=0) {
			System.out.println("栈为空!");
			return;
		}
		System.out.print("当前栈中元素:");
		for(int i = 0;i<length;i++) {
			System.out.print(data[i]+" ");
		}
		System.out.println("");
	}
	
	public static void main(String[] args) {
		int []a = {1,2,4,5,6};
		Stack st = new Stack(a);
		st.Reverse();
		st.pop();
		st.Reverse();
		st.pop();
		st.Reverse();
		st.pop();
		st.Reverse();
		st.pop();
		st.Reverse();
		st.pop();
		st.Reverse();
		st.push(1);
		st.Reverse();
		st.push(2);
		st.Reverse();
		st.push(3);
		st.Reverse();
		st.push(4);
		st.Reverse();
		st.push(5);
		st.Reverse();
	}//main方法进行测试

}
当前栈中元素:1 2 4 5 6 
当前栈中元素:1 2 4 5 
当前栈中元素:1 2 4 
当前栈中元素:1 2 
当前栈中元素:1 
栈为空!
当前栈中元素:1 
当前栈中元素:1 2 
当前栈中元素:1 2 3 
当前栈中元素:1 2 3 4 
当前栈中元素:1 2 3 4 5 

2021.12.30

栈的应用,进行括号匹配

整个代码最需要注意的地方就是switch当中不使用break的话,会继续执行接下来的代码,会导致结果错误。只需要将括号放入栈,之后遇到不同的括号,进行匹配。每次匹配前弹栈。这样做的好处,就算遇到不符合的情况,直接返回false,无需再去计算。

package basic;

public class BracketMatching {
	//这里我就默认外部输入的数组长度是小于MAX_SIZE了,就不加条件判断了。
	public static final int MAX_SIZE=20;//定义顺序栈容量
	char []data;//栈中数组。
	int length = 0;//当前栈中元素数量。
	public  BracketMatching() {
		data = new char[MAX_SIZE];
	}
	
	public void push(char elem) {
		if(length>=MAX_SIZE) {
			System.out.println("当前栈已满,添加失败!");
			return;
		}
		data[length++] = elem;
	}//压栈
	
	public char pop() {
		if(length<=0) {
//			System.out.println("当前栈已空,删除失败!");
			return '?';
		}
		char temp = data[length-1];
		length--;
		return temp;
	}//弹栈
	
	public char GetTop() {
		return data[length-1];
	}//获取顶部元素
	
	public int ElemNum() {
		return length;
	}//当前栈元素数
	
	public void Reverse() {
		if(length<=0) {
			System.out.println("栈为空!");
			return;
		}
		System.out.print("当前栈中元素:");
		for(int i = 0;i<length;i++) {
			System.out.print(data[i]+" ");
		}
		System.out.println("");
	}
	
	public boolean BracketMatchingMethod(String arr) {
		BracketMatching brack = new BracketMatching();//单独判断的话就随便建一个吧,无所谓
		char temp,poptemp;
		if(arr.length()==0) return false;
		for(int i = 0;i<arr.length();i++) {
			temp = arr.charAt(i);
			switch(temp) {//如果全输入左边部分,不进行判断直接压栈
			//采用
			case '[':
			case '{':
			case '(':
				brack.push(temp);
				break;
			
			case ']':
				poptemp = brack.pop();//不采用break的话,后面的pop会继续执行,整个代码最需要注意的地方应该就是这里了
				if(poptemp!='[') {
					return false;
				}
				break;
			case '}':
				poptemp = brack.pop();
				if(poptemp!='{') {
					return false;
				}
				break;
			case ')':
				poptemp = brack.pop();
				if(poptemp!='(') {
					return false;
				}
				break;
			default:
			}
			
		}
		if(brack.ElemNum()!=0) return false;
		else return true;
	}
	
	public static void main(String[] args) {
		int []a = {1,2,4,5,6};
		BracketMatching st = new BracketMatching();
		String test = "[]12[fds] {(fijo)}";
		boolean result = st.BracketMatchingMethod(test);
		System.out.println(result);
		test = "[[]}";
		System.out.println(st.BracketMatchingMethod(test));	
	}//main方法进行测试

}
true
false

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值