数据结构中的链表,数组,队列,栈(C++模板实现)

链表、数组、队列和栈都是常见的数据结构,用于存储和组织数据。它们在不同情况下有不同的特点和应用。

数组(Array)

1.数组是一种线性数据结构,元素在内存中是连续存储的。

2.元素可以通过索引访问,索引通常从0开始。

3.插入和删除操作的效率较低,时间复杂度为O(n),但查找操作的效率较高,时间复杂度为O(1)。

C++代码实现:

#include <iostream>
using namespace std;
//分数类
class CFraction {
	int numerator, denominator;   //分子分母
public:
	CFraction(int n, int d) :numerator(n), denominator(d) { };
	bool operator <(const CFraction& f) const
	{//为避免除法产生的浮点误差,用乘法判断两个分数的大小关系
		if (denominator * f.denominator > 0)
			return numerator * f.denominator < denominator * f.numerator;
		else
			return numerator * f.denominator > denominator * f.numerator;
	}
	bool operator == (const CFraction& f) const
	{//为避免除法产生的浮点误差,用乘法判断两个分数是否相等
		return numerator * f.denominator == denominator * f.numerator;
	}
	friend ostream& operator <<(ostream& o, const CFraction& f);
};

template <class T> //声明函数模板
T MaxElement(T a[], int size) //定义函数体
{
	//函数功能:找出数组中的最大值
	T max_v = a[0];
	for (int i = 1; i < size; i++) {
		if (max_v < a[i]) {
			max_v = a[i];
		}
	}
	return max_v;
}
ostream& operator <<(ostream& o, const CFraction& f) //重载 << 使得分数对象可以通过cout输出
{
	o << f.numerator << "/" << f.denominator << endl; //补充代码,输出"分子/分母" 形式
	return o;
}
int main()
{
	int a[5] = { 1,5,2,3,4 };//定义整数数组
	CFraction f[4] = { CFraction(8,6),CFraction(-8,4),
		CFraction(3,2), CFraction(5,6) };//定义分数类数组对象
	int maxInt = MaxElement(a, 5);//调用模板函数MaxElement输出整数数组a的最大值
	cout << "整数集合a[]的最大值为:" << maxInt << endl;
	CFraction maxFraction = MaxElement(f, 4); //调用模板函数MaxElement和重载运算符函数”<<”输出分数数组对象的最大值
	cout << "分数集合f[]的最大值为:" << maxFraction << endl;
	return 0;
}

链表(Linked List)

1.链表是由一系列节点组成的数据结构,每个节点包含数据和指向下一个节点的指针。

2.分为单向链表和双向链表。单向链表的节点只有指向下一个节点的指针,而双向链表的节点除了指向下一个节点的指针外,还有指向前一个节点的指针。

3.插入和删除操作效率高,时间复杂度为O(1),但查找操作的效率较低,时间复杂度为O(n)。

C++代码实现:

#include<iostream>
using namespace std;
//定义结点模板类
template <class T> //前置申明模板类
class Node //定义一个Node类 
{
public:
	Node(T _value) //构造函数 
	{
		value = _value;
		next = NULL;
	}
public:
	T value; //结点数据域
	Node* next; //结点指针域,指向后继结点
};
//定义链表模板类
template <class T> //申明模板类
class List //定义List类 
{
public:
	List()
	{
		ptr_head = NULL; //初始化链表头结点
		ptr_tail = NULL; //初始化链表尾结点
	}
	void insertnodelist(T _value); //插入结点
	void printlist(); //输出结点
	void findlist(T value1); //查找结点

public:
	Node<T>* ptr_head; //链表头结点
	Node<T>* ptr_tail; //链表尾结点
};
//定义链表模板类
template <class T> //类外实现函数时该语句不能省!
void List<T>::insertnodelist(T _value) //类外实现插入结点函数
{
	Node<T>* ptr_new = new Node<T>(_value); //创建新结点
	if (ptr_head == NULL)
	{
		ptr_head = ptr_new; //如果头结点的后继指针为空,则该结点为头结点
	}
	else
	{
		ptr_tail->next = ptr_new; //链表尾结点指向新插入的结点
	}
	ptr_tail = ptr_new; //新插入的结点变为尾结点
}
//定义链表模板类
template <class T> //类外实现函数时该语句不能省!
void List<T>::printlist() //类外实现输出链表函数
{
	Node<T>* current = ptr_head;
	while (current != NULL) {
		cout << current->value << " ";
		current = current->next;
	}
	cout << endl;
}

template <class T> //类外实现函数时该语句不能省!
void List<T>::findlist(T value1) //类外实现查找链表函数
{
	Node<T>* current = ptr_head;
	while (current != NULL) {
		if (current->value == value1) {
			cout << "找到: " << value1 << endl;
			return;
		}
		current = current->next;
	}
	cout << "未找到: " << value1 << endl;
}
int main()
{
	List<int> list; //定义对象,使用时确定数据成员类型
	list.insertnodelist(1); //创建链表
	list.insertnodelist(2);
	list.insertnodelist(5);
	list.printlist(); //输出链表
	list.findlist(3); //查找链表中某个数
	return 0;
}

队列(Queue)

1.队列是一种先进先出(FIFO)的数据结构,类似于排队。

2.元素只能从队尾入队,从队首出队。

3.常见的队列有普通队列、优先级队列和循环队列。

C++代码实现:

#include<iostream> 
using namespace std;
const int MaxQSize = 50;
template <class T>
class Queue
{
private:
	int front, rear, count;  //队头指针、队尾指针、元素个数
	T qlist[MaxQSize];  //队列元素数组
public:
	Queue() :front(0), rear(0), count(0) {}   //构造函数
	void QInsert(const T& item);  //新元素入队
	T QDelete(void);  //元素出队
	void ClearQueue(void);  //清空队列
	T QFront(void) const;  //访问队首元素
	int QLength(void) const; //求队列长度(元素个数)
	int QEmpty(void) const; //判队队列空否
	int QFull(void) const; //判断队列满否
	void showdate();
};
template <class T>
void Queue<T>::QInsert(const T& item) //向队尾插入元素(入队)
{
	if (count == MaxQSize) // 如果队满,中止程序
	{
		std::cerr << "Queue overflow!" << endl;
		exit(1);
	}
	count++; //元素个数增1
	qlist[rear] = item; //向队尾插入元素
	rear = (rear + 1) % MaxQSize; //队尾指针增1,用取余运算实现循环队列
}
template <class T>
T Queue<T>::QDelete(void) //删除队首元素,并返回该元素的值(出队)
{
	T temp;
	if (count == 0) // 如果队空,中止程序
	{
		std::cerr << "Deleting from an empty queue!" << endl;
		exit(1);
	}
	temp = qlist[front]; // 记录队首元素值
	count--; // 元素个数自减
	front = (front + 1) % MaxQSize; //队首指针增1。取余以实现循环队列
	return temp; //返回首元素值
}
template <class T>
T Queue<T>::QFront(void) const // 访问队列首元素(返回其值)
{
	return qlist[front];
}
template <class T>
int Queue<T>::QLength(void) const // 返回队列元素个数
{
	return count;
}
template <class T>
int Queue<T>::QEmpty(void) const // 测试队空否
{
	return count == 0;//返回逻辑值 count == 0
}
template <class T>
int Queue<T>::QFull(void) const // 测试队满否
{
	return count == MaxQSize; // 返回逻辑值 count == MaxQSize
}
template <class T>
void Queue<T>::ClearQueue(void)
{
	// 清空队列
	count = 0;
	front = 0;
	rear = 0;
}
template <class T>
void Queue<T>::showdate()
{
	cout << "当前队列数据为:";
	for (int i = 0; i < count; i++)
		cout << " " << qlist[i];
	cout << endl;
}
int main()
{
	const int a[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
	Queue<int> s;
	int n;
	cout << "请输入要进行的操作次数:";
	cin >> n;
	while (n--)
	{
		int operation;
		cout << "请输入操作:(1 表示入队,0 表示出队)";
		cin >> operation;
		if (operation == 1)
		{
			int index;
			cout << "请输入要入队的元素下标:";
			cin >> index;
			s.QInsert(a[index]);
		}
		else if (operation == 0)
		{
			s.QDelete();
		}}
	s.showdate();
	return 0;
}

栈(Stack)

1.常见的应用包括函数调用栈、表达式求值和浏览器历史记录等。

2.元素只能从栈顶压入(push)和弹出(pop)。

3.栈是一种后进先出(LIFO)的数据结构,类似于一摞盘子。

C++代码实现:

const int maxsize = 100;
template <typename T>     
class Stack
{
private:
    T elems[maxsize];   //elems数组用于存储栈的数据元素
    int top;  //栈顶的位置
public:
    Stack() {       top = 0;    }
    void push(T e);  //入栈
    T pop();  //出栈
    bool empty(); //判断栈是否为空
    bool full(); //判断栈是否满
};
template <typename T>
bool Stack<T>::empty()
 {
    if (top == 0) //判断栈是否为空
        return true;
    else
        return false;
}
template <typename T>
bool Stack<T>::full() 
{
    if (top == maxsize) //判断栈是否满
        return true;
    else
        return false;
}
template <typename T>
void Stack<T>::push(T e)
 {
    if (!full())
        elems[top++] = e; //入栈
}
template <typename T>
T Stack<T>::pop()
 {
    if (!empty())
        return elems[--top]; //出栈
}
void main()
{
    int n,e;
    while (cin >> n)
    {
        Stack<int> s;//定义堆栈对象
        while (n--)
        {
            cin >> e;
            s.push(e);//入栈
        }  
cin >> n;
        while (n--)  //出栈
        {
            if (!s.empty())
                cout << s.pop();
            else
                cout << "empty!!";
            if (n)
                cout << " ";//注意这里的格式是每两个数或字符串或数与字符串之间有空格
        }
        cout << endl;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值