数据结构——双链表(C++版)

  1. 基本思路
    用三个数组模拟双链表,提高时间效率
  2. 模板
// e[]表示节点的值,l[]表示节点的左指针,r[]表示节点的右指针,idx表示当前用到了哪个节点
int e[N], l[N], r[N], idx;

// 初始化
void init()
{
    //0是左端点,1是右端点
    r[0] = 1, l[1] = 0;
    idx = 2;
}

// 在节点a的右边插入一个数x
void insert(int a, int x)
{
    e[idx] = x;
    l[idx] = a, r[idx] = r[a];
    l[r[a]] = idx, r[a] = idx ++ ;
}

// 删除节点a
void remove(int a)
{
    l[r[a]] = l[a];
    r[l[a]] = r[a];
}
  1. 例题:双链表
    实现一个双链表,双链表初始为空,支持5种操作:
    (1) 在最左侧插入一个数;
    (2) 在最右侧插入一个数;
    (3) 将第k个插入的数删除;
    (4) 在第k个插入的数左侧插入一个数;
    (5) 在第k个插入的数右侧插入一个数
    现在要对该链表进行M次操作,进行完所有操作后,从左到右输出整个链表。
    注意:题目中第k个插入的数并不是指当前链表的第k个数。例如操作过程中一共插入了n个数,则按照插入的时间顺序,这n个数依次为:第1个插入的数,第2个插入的数,…第n个插入的数。
    输入格式
    第一行包含整数M,表示操作次数。
    接下来M行,每行包含一个操作命令,操作命令可能为以下几种:
    (1) “L x”,表示在链表的最左端插入数x。
    (2) “R x”,表示在链表的最右端插入数x。
    (3) “D k”,表示将第k个插入的数删除。
    (4) “IL k x”,表示在第k个插入的数左侧插入一个数。
    (5) “IR k x”,表示在第k个插入的数右侧插入一个数。
    输出格式
    共一行,将整个链表从左到右输出。
    数据范围
    1≤M≤100000
    1≤M≤100000
    所有操作保证合法。
    输入样例:
    10
    R 7
    D 1
    L 3
    IL 2 10
    D 3
    IL 2 7
    L 8
    R 9
    IL 4 7
    IR 2 2
    输出样例:
    8 7 7 3 2 9
#include<iostream>

using namespace std;

const int N = 100010;

int m;
int e[N], r[N], l[N], idx;	// e[N]存储数据,r[N]存储右指针,l[N]存储左指针,idx表示当前操作的数组下标

//函数功能:初始化
//注:数组下标为0和1的节点不是链表的内容,实际的链表下标从2开始
void init()
{
	r[0] = 1, l[1] = 0;
	idx = 2;
}

//函数功能:在第k个插入的节点有边插入一个新节点
void add(int k, int x)
{
	e[idx] = x;
	r[idx] = r[k];
	l[idx] = k;
	l[r[k]] = idx;
	r[k] = idx ++;
}

//函数功能:删除下标为k的节点
void remove_1(int k)
{
	r[l[k]] = r[k];
	l[r[k]] = l[k];
}

int main()
{	
	cin >> m;

	init();

	string op;
	int k, x;
	
	while (m--)
	{
		cin >> op;
		if(op == "L")
		{
			cin >> x;
			add(0, x);	//首节点为下标为r[0]所指的节点
		}
		else if(op == "R")
		{
			cin >> x;
			add(l[1], x);	//尾结点为l[1]所指的节点
		}
		else if(op == "D")
		{
			cin >> k;
			remove_1(k+1);	// 第k个插入的数对应的下标为k+1
		}
		else if(op == "IL")
		{
			cin >> k >> x;
			add(l[k+1], x);
		}
		else 
		{
			cin >> k >> x;
			add(k+1, x);
		}
	}

	for(int i = r[0]; i != 1; i = r[i]) printf("%d ", e[i]);

	return 0;
}							
	
		

[^1]此文章中的代码和模板均来自www.acwing.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package 单双向链表; /** * 单向链表增删改查操作 * */ public class LinkTest { public static void main(String[] args) { Link l=new Link(); l.addNode("A"); l.addNode("B"); l.addNode("C"); l.addNode("D"); l.addNode("E"); l.printNode(); System.out.println("\n是否包含D:"+l.contains("D")); System.out.println("==========删除之前的内容=========="); l.printNode(); System.out.println("\n==========删除之后的内容=========="); l.deleteNode("A"); l.printNode(); } } class Link{//链表的完成类 class Node{//保存每个节点 private String data;//节点内容 private Node next;//下一个节点 public Node(String data){ this.data=data; } public void add(Node newNode) {//将节点加入到合适的位置 if(this.next==null){ this.next=newNode; }else{ this.next.add(newNode); } } public void print() {//输出节点的内容 System.out.print(this.data+"\t"); if(this.next!=null){ this.next.print();//递归调用输出 } } public boolean search(String data){//内部搜索的方法 if(data.equals(this.data)){ return true; }else{ if(this.next!=null){//向下继续判断 return this.next.search(data); }else{ return false; } } } public void delete(Node previous, String data) { if(data.equals(this.data)){//找到了匹配的节点 previous.next=this.next;//空出当前的节点 }else{ if(this.next!=null){ this.next.delete(this, data);//继续查找 } } } } private Node root;//链表中的根节点 public void addNode(String data){//增加节点 Node newNode=new Node(data); if(root==null){ root=newNode; }else{ root.add(newNode); } } public void printNode(){//链表的输出 if(root!=null){ root.print(); } } public boolean contains(String name){//判断元素是否存在 return this.root.search(name); } public void deleteNode(String data){//链表删除节点 if(this.contains(data)){ if(this.root.data.equals(data)){//如果是根节点 this.root=this.root.next;//修改根节点 }else{ this.root.next.delete(root,data);//把下一个节点的前节点和要删除的节点内容一起传入 } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值