数据结构与算法——单链表,顺序栈,链栈等的建立可以使用for循环一个一个元素的插入数据,包括双向链表也是

本文深入解析栈、队列和链表三种基本数据结构的实现与应用,涵盖单链表的建立、查找、插入与删除操作,顺序栈的创建、入栈、出栈及按值查找,以及链队列的入队和出队过程。通过具体代码示例,帮助读者理解这些数据结构的工作原理和实际编程技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**本质上是你遇到了需要"后入先出""先入先出"的问题,所以你构建了出入栈,出入队列的方法,
所以才有了栈和队列这种数据结构,而不是本来就有这种数据结构,栈和队列本质上是线性表,
只不过你改变了其插入数据和删除数据的方法,才有了栈和队列!!!**

单链表,顺序栈,链栈等的建立可以使用for循环一个一个元素的插入数据啊,包括双向链表也是啊

1. 单链表

1.1 单链表的建立:由数组建立单链表

//节点类
public class Node{
	public Object val;
	public Node next;
	public Node() {
		this.val = null;
	}
	public Node(Object val) {
		this.val = val;
	}
}
//由数组建立链表
import java.util.Scanner;

public class Main1 {

	//由数组建立链表
	public static Node arrryToNode(int[] arr) {
		Node head = new Node(); //建立头节点
		Node other = head;//建立头指针指向头节点
		
		for(int i=0;i<arr.length;i++) {
			Node temp = new Node(arr[i]);
			other.next = temp;
			other = other.next;
		}
		return head;
	}
	
	//打印链表
	public static void printNode(Node temp) {
		Node node = temp.next;
		while(node!=null) {
			System.out.println(node.val);
			node = node.next;
		}
	}
	
   
	    public static void main(String[] args){
	        Scanner sc = new Scanner(System.in);
	        String str1 = sc.nextLine();
	        String[] str2 = str1.split(" ");
	        int[] arr = new int[str2.length];
	        for(int i=0;i<str2.length;i++) {
	        	arr[i] = Integer.parseInt(str2[i]);
	        }
	        Node node = arrryToNode(arr);
	        printNode(node);
	        System.out.println(get(node,3));
	        System.out.println(indexOf(node,4));
	        
	    }
    
}

1.2 单链表的查找操作

1.2.1 位序查找:位序查找get(i)是返回长度为n的单链表中索引为i的节点的数据域的值,其中0<=i<=n-1。由于单链表的存储空间不连续,因此必须从头结点开始沿着后继节点依次进行查找。

	//位序查找
	public static Object get(Node node,int i){
		Node p = node;
		for(int j=0;j<=i&&p!=null;j++) {//node就是头节点,所以j从0开始,j要到i
			p = p.next;
		}

		return p.val;
	}

1.2.2 按值查找:查找操作indexOf(x)是在长度为n的单链表中寻找初次出现的数据域值为x的数据元素的位置。其主要步骤为将x与单链表中的每一个数据元素的数据域进行比较,若相等,则返回该数据元素在单链表中的位置;若比较结束未找到等值的数据元素,返回-1。

	//按值查找
	public static int indexOf(Node node,int x){
		Node p = node.next;
		int j=0;
		while(p!=null&&!p.val.equals(x)){
			p = p.next;
			j++;
		}
		if(p!=null) {//上面while循环的停止原因可能是p==null或者p.val==x,排除p==null的可能
			return j;
		}
		else {
			return -1;
		}
		
	}

1.3 插入操作:insert(Node node,int i,object x)。

在这里插入图片描述

//插入操作
public  static void insert(Node node,int i,Object x) {
	Node p = node.next;
	int j = 0;
	while(p!=null&&j<i-1) {//注意j<i-1,不能定为j<i
		p = p.next;
		j++;
	}
	Node s = new Node(x);
	s.next = p.next;//注意:一定要先把p.next赋值给s.next,然后再把s赋值给p.next,顺序一定不能颠倒
	p.next = s;
	printNode(node);
	
}

1.4 删除操作:remove(Node node,int i)
在这里插入图片描述

//删除操作
public  static void remove(Node node,int i) {
	Node p = node.next;
	int j = 0;
	while(p!=null&&j<i-1) {//注意j<i-1,不能定为j<i
		p = p.next;
		j++;
	}
	p.next = p.next.next;
	printNode(node);
	
}

2. 栈

2.1 顺序栈

2.1.1 顺序栈的查找

2.1.1.1 按索引查找

顺序栈一般用数组实现,所以用索引查找元素时直接用stackElem[i]查找即可。

2.1.1.2 按值查找

顺序栈与数组的一点区别就是顺序栈的按值查找中的for循环必须从表的尾部开始。

for(int i=stackElem.length-1;i>=0;i--) {
	if(stackElem[i]==x) {
		retnrn i;
	}
}

2.1.2 顺序栈的建立,打印,出栈,入栈

import java.util.Scanner;

public class SQStack {

	public int[] stackElem;//顺序栈存储空间
	public int top;//指向栈顶元素存储位置的下一个存储单元的位置
	public int maxSize;//栈的最大存储单元个数
	

	/*
	//构造最大存储单元个数为maxSize的空栈
	 
	public SQStack(int maxSize) {
		top = 0;
		this.maxSize = maxSize;
		stackElem = new int[maxSize];
	}
	*/

	
	//单链表,顺序栈,链栈等的建立可以使用for循环一个一个元素的插入数据啊,包括双向链表也是啊
	//输出栈中的所有元素,要从栈顶开始输出
	public static void display(int[] stackElem,int top) {
		for(int l=top-1;l>=0;l--) {
			System.out.println(stackElem[l]+"");
		}
	}
	
	//入栈操作
	public static int[] push(int[] stackElem,int maxSize,int top,int x) throws Exception{
		if(top == maxSize) {
			throw new Exception("栈已满");
			
		}
		stackElem[top] = x;
		top++;
		display(stackElem,top);

	
		return stackElem;
	}
	
	//出栈操作
	public static int[] pop(int[] stackElem,int maxSize,int top) {

		top--;
        for(int i=0;i<top;i++) {
        	System.out.print(stackElem[i]);
        }
		return stackElem;
	}
	
    public static void main(String[] args) throws Exception{
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();
        String[] str2 = str1.split(" ");
        int[] arr = new int[str2.length];
        for(int i=0;i<str2.length;i++) {
        	arr[i] = Integer.parseInt(str2[i]);
        }
     int maxSize = arr.length * 2;
     int top = 0;
     int[] stackElem = new int[maxSize];
     for(int j=0;j<arr.length;j++) {
 		stackElem[top] = arr[j];
 		top++;
 		display(stackElem,top);

     }

}
}
  1. 队列
import LinkList.Node;

public class LinkQueue {

	/*
	 * 链队列用单链表实现,由于入队和出队分别在队列的队尾和队首进行,
	 * 不存在在队列的任意位置进行插入和删除的情况,所以不需要设置头结点,
	 * 只需要将指针front和rear分别指向队首节点和队尾节点,每个节点的指针域指向其后继节点即可
	 */
	public Node front;
	public Node rear;
	
	//入队
	public void offer(Object x) {
		Node s = new Node(x);
		if(front != null) {
			rear.next = s;
			rear = s;
		}
		else {
			front = rear = s;
		}
	}
	
	//出队
	public Object poll(){
		if((front == null)) {
			return null;
		}
		Node p = front;
		front = front.next;
		if(p == rear) {  //删除节点为队尾节点时需要修改rear
			rear = null;
		}
		return p.data;
	}
	
	//输出队列中的所有数据元素
	public void display() {
		if(front != null) {
			for(Node p = front;p!=null;p=p.next) {
				System.out.print(p.data + "");
			}
		}
		else {
			System.out.print("此队列为空");
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值