栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构之线性表

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构之线性表

非连续内存线性表

非连续内存线性表,C++ list 单链表 简单实现 同时也是栈结构的实现

#include 

using namespace std;

template class lifo{//先实现一个简单的list
public:
	lifo() {
		this->data = 0;
		this->next = nullptr;
	}
	void in(T value) {
		lifo *insert =  new lifo; //首先先进行初始化,作为首地址
		insert->data = value; //进行值的插入
		insert->next = this->end;
		this->end = insert;
	}

	void printList(void) {
		while (this->end != nullptr) { //需要使用一个临时变量,替换替代一下
			cout << "index: " << this->end->data<< endl;
			this->end = this->end->next;
		}
	}
private:
	T data;
	lifo* end; //必须多出一个尾指针进行使用, 记录线性表开始遍历的地址;
	lifo* next;
};

int main(void) {
	lifo test;
	test.in(1);
	test.in(2);
	test.in(3);
	test.in(4);
	test.printList();
}

C++ 中 无法修改 this 指针的地址(仔细想想也应该)所以不能像C中使用的那样 可移动初始地址,作为数据遍历的头部 上面的代码是头插法

template class fifo {
public:
	fifo() {
		this->data = 0;
		this->next = nullptr;
	}
	void in(T value) {
		fifo* node = new fifo;
		node->data = value;
		if (this->ptr == nullptr) {
			this->ptr = node;
		}
		else {
			this->tmp->next = node;
		}
		this->tmp = node;
		node->next = nullptr;
	}

	void printList(void) {
		//fifo* tmp = this;
		while (ptr != nullptr) { //需要使用一个临时变量,替换替代一下
			cout << "index: " << ptr->data << endl;
			ptr = ptr->next;
		}
	}
	
private:
	T data;
	fifo* ptr; //线性表的头部, 实际常说的迭代器
	fifo* tmp; //需要迭代移动的指针
	fifo* next; //链接地址使用
};

int main(void) {
	fifo test;
	test.in(1);
	test.in(2);
	test.in(3);
	test.in(4);
	test.printList();
}

这里面的new 和 delete 操作可以受用 auto_ptr 替代,会更加省心
C++ 中有现成的算法容器.以上只为熟悉类的内存分布和使用

// Cplus数据结构阶段复习three.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 

//循环列表约瑟夫问题
//

using namespace std; //双向结构的好处在与,在任何一个地址下,都可以进行遍历
template class circle {
public:
	
	circle() { //无参构造方法
		// cout << "no para init" << endl;
		this->data = 0;
		this->next = nullptr;
	}

	circle(T v) :data(v) { //有参构造方法
		// cout << "one para init" << endl;
		this->in(this->data);
	}

	void in(T value) {
		circle* node = new circle;
		node->data = value;
		if (this->ptr == nullptr) {
			this->ptr = node; //确立第一个节点的位置
			this->begin = node;
		}
		else {
			this->tmp->next = node;
			node->pre = this->tmp;
		}

		this->tmp = node;
		this->end = this->tmp;

		//完成首尾循环建立
		this->end->next = this->begin;
		this->begin->pre = this->end;
		size++;
	}

	void printList(void) {
		//fifo* tmp = this;
		while (size--) { // 循环建立表成功; 设置退出条件
			cout << "index: " << end->data << endl;
			end = end->pre;
		}
	}

	T get_begin_data(void) {
		return this->begin->data;
	}

	T get_end_value(void) {
		return this->end->data;
	}

private:
	T data;
	int size=0;
	circle* begin; //循环时需要用到的头部指针
	circle* end;	//循环时需要用到的尾部指针
	circle* ptr;	//线性表的头部, 实际常说的迭代器
	circle* tmp;	//需要迭代移动的指针
	circle* pre;	//前驱链接地址
	circle* next;	//后继链接地址使用
};

int main(void) {
	circle test(19); //需要实现一个构造时初始值的复制, 初始化的第一个值,一个list基类基本可以使用
	test.in(1);
	test.in(2);
	test.in(3);
	test.in(4);

	test.printList(); 
}

FIXME 概述一下约瑟夫环的问题:
按照约定的规则删除,环形表中的数据, (能不能并发删除,这是一个好的问题,单步删除倒是很容易想到?)
最后只剩下一个数据元素(我用 bitmap 直接删除会不会更爽?)

使用栈实现就近匹配原则: 简单的匹配左右括号

// Cplus数据结构阶段复习three.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 

//循环列表约瑟夫问题
//

using namespace std; //双向结构的好处在与,在任何一个地址下,都可以进行遍历
template class circle {
public:
	
	circle() { //无参构造方法
		// cout << "no para init" << endl;
		this->data = 0;
		this->next = nullptr;
	}

	circle(T v) :data(v) { //有参构造方法
		// cout << "one para init" << endl;
		this->in(this->data);
	}

	void in(T value) {
		circle* node = new circle;
		node->data = value;
		if (this->ptr == nullptr) {
			this->ptr = node; //确立第一个节点的位置
			this->begin = node;
		}
		else {
			this->tmp->next = node;
			node->pre = this->tmp;
		}

		this->tmp = node;
		this->end = this->tmp;

		//完成首尾循环建立
		this->end->next = this->begin;
		this->begin->pre = this->end;
		size++;
	}

	void printList(void) {
		//fifo* tmp = this;
		while (size--) { //需要使用一个临时变量,替换替代一下; 循环建立表成功
			cout << "index: " << end->data << endl;
			end = end->pre;
		}
	}

	T get_begin_data(void) {
		return this->begin->data;
	}

	T get_end_value(void) {
		return this->end->data;
	}

private:
	T data;
	int size=0;
	circle* begin; //循环时需要用到的头部指针
	circle* end;	//循环时需要用到的尾部指针
	circle* ptr;	//线性表的头部, 实际常说的迭代器
	circle* tmp;	//需要迭代移动的指针
	circle* pre;	//前驱链接地址
	circle* next;	//后继链接地址使用
};

template class lifo {//先实现一个简单的list
public:
	lifo() {
		this->data = 0;
		this->next = nullptr;
	}
	void in(T value) {
		lifo* insert = new lifo; //首先先进行初始化,作为首地址
		insert->data = value; //进行值的插入
		insert->next = this->end;
		this->end = insert;
		size++;
	}

	void out(void) {
		if (size == 0) {
			return;
		}
		lifo* tmp = this->end;
		this->end = this->end->next; //移动到最新的栈顶

		delete[] tmp; //释放弹出的栈顶内存空间
		tmp = nullptr;
		size--;
	}

	T stack_top(void) {
		if (this->end != nullptr)
			return this->end->data;

		return 0; //返回一个空顶,用以判断栈顶不存在该元素
	}

	void printList(void) {
		while (this->end != nullptr) { //需要使用一个临时变量,替换替代一下
			cout << "index: " << this->end->data << endl;
			this->end = this->end->next;
		}
	}
private:
	int size=0;
	T data;
	lifo* end; //必须多出一个尾指针进行使用, 记录线性表开始遍历的地址;
	lifo* next;
};

int main(void) {
	//circle test(19); //需要实现一个构造时初始值的复制, 初始化的第一个值,一个list基类基本可以使用
	//test.in(1);
	//test.in(2);
	//test.in(3);
	//test.in(4);

	//test.printList(); 

	char text[] = "hello world))"; //栈的使用就近匹配原则;
	
	int len = strlen(text);
	lifo check;
	int check_sym = 0;
	try {
		for (int i = 0; i < len; i++) { //常见的括号匹配
			if (text[i] == '(') {
				check.in(text[i]); //入栈
				check_sym++;
			}
			else if (text[i] == ')') {
				if (check.stack_top() == '(')
				{
					check.out(); //左括号出栈; 如果匹配就说明没有任何问题
				}
				else {
					cout << "括号不匹配" << endl;
					throw i;
				}
			}
		}
	}
	catch(int error){
		cout << "右括号不匹配: " << text << endl;
		text[error] = '';
		cout << "右括号不匹配: " << text << endl;
	}

	if (check_sym == 0) {
		cout << "缺少左括号" << endl;
	}
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/429418.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号