【数据结构与算法】线性结构

机器感知
一个专注于SLAM、三维重建、机器视觉、Linux 等相关技术文章分享的公众号
线性结构
1. 单链表
#ifndef __LINK1__H__
#define __LINK1__H__

#include <iostream>
using namespace std;

template<typename T>
struct sigleLink {
	T value;
	struct sigleLink<T>* next;
};

template<typename T>
class Link1 {
public:
	Link1():head(NULL),count(0){}	
	bool isEmpty();
	void add(T value);
	void del();
	int size();
	T getTail();
	T getHead();
private:
	struct sigleLink<T>* head;
	int count;
};

template<typename T>
bool Link1<T>::isEmpty()
{
	return count==0;
}

template<typename T>
void Link1<T>::add(T value)
{
	if (!head) {
		head = new sigleLink<T>();
		head->value = value;
		head->next = NULL;
	} else {
		struct sigleLink<T>* temp = head;
		while(temp->next) {
			temp = temp->next;
		}
		temp->next = new sigleLink<T>();
		temp = temp->next;
		temp->value = value;
	}
	count++;
}

template<typename T>
int Link1<T>::size()
{
	return count;
}

template<typename T>
T Link1<T>::getHead()
{
	return head->value;
}

template<typename T>
T Link1<T>::getTail()
{
	if(!head) {
		cout << "there is no data!" << endl;
		return false;
	} else {
		struct sigleLink<T>* temp = head;
		while(temp->next) {
			temp = temp->next;
		}
		return temp->value;
	}	
}

template<typename T>
void Link1<T>::del()
{
	if(isEmpty()) {
		cout << "there is no data to delete!" << endl;
	} else {
		struct sigleLink<T>* temp1 = head;
		struct sigleLink<T>* temp2 = head->next;
		while(temp2->next) {
			temp2 = temp2->next;
			temp1 = temp1->next;
		}
		temp1->next = NULL;
		delete temp2;
	}
	count--;
}

#endif
#include <iostream>
#include "Link1.h"
using namespace std;

int main(int argc, char** argv)
{
	Link1<int> lk1;
	lk1.del();
	lk1.add(10);
	lk1.add(20);
	lk1.add(30);
	lk1.add(40);
	lk1.add(50);
	cout << lk1.size() << endl;
	cout << lk1.getHead() << endl;
	cout << lk1.getTail() << endl;
	lk1.del();
	cout << lk1.size() << endl;
	cout << lk1.getHead() << endl;
	cout << lk1.getTail() << endl;	
	return 0;
}
2. 双链表
#ifndef __Link2__H__
#define __Link2__H__
#include <iostream>
using namespace std;

template<typename T>
struct doubleLink {
	doubleLink():prev(NULL),next(NULL) {}
	T value;
	struct doubleLink<T>* prev;
	struct doubleLink<T>* next;
};

template<typename T>
class Link2 {
public:
	Link2():head(NULL),count(0){}	
	bool isEmpty();
	void add(T value);
	void del();
	int size();
	T getTail();
	T getHead();
	void cLink2();
private:
	struct doubleLink<T>* head;
	int count;
};

template<typename T>
bool Link2<T>::isEmpty()
{
	return count==0;
}

template<typename T>
void Link2<T>::add(T value)
{
	struct doubleLink<T>* pdLink = new doubleLink<T>;
	if (!head) {
		head = pdLink;
		head->next = NULL;
		head->prev = NULL;
	} else {
		struct doubleLink<T>* temp = head;
		while(temp->next) {
			temp = temp->next;
		}
		temp->next = pdLink;
		pdLink->prev = temp;
	}
	pdLink->value = value;
	count++;
}

template<typename T>
int Link2<T>::size()
{
	return count;
}

template<typename T>
T Link2<T>::getHead()
{
	if(!head) {
		cout << "there is no data!" << endl;
		return false;
	} else {
		return head->value;
	}
}

template<typename T>
T Link2<T>::getTail()
{
	if(!head) {
		cout << "there is no data!" << endl;
		return false;
	} else {
		struct doubleLink<T>* temp = head;
		while(temp->next) {
			temp = temp->next;
		}
		return temp->value;
	}	
}

template<typename T>
void Link2<T>::del()
{
	if(isEmpty()) {
		cout << "there is no data to delete!" << endl;
	} else {
		struct doubleLink<T>* temp = head;
		while(temp->next) {
			temp = temp->next;
		}
		if(temp!=head) {
			temp->prev->next = NULL;
		} else {
			head = NULL;
		}		
		delete temp;
		count--;
	}
}

template<typename T>
void Link2<T>::cLink2()
{
	if(isEmpty()) {
		cout << "Link2 is empty!" << endl;
	} else {
		struct doubleLink<T>* temp = head;
		while(temp->next) {
			cout << temp->value << "->";
			temp = temp->next;
		}
		cout << temp->value << endl;
	}
}

#endif
#include <iostream>
#include "Link2.h"
using namespace std;

int main(int argc, char** argv)
{
	Link2<int> lk2;
	lk2.del();
	lk2.add(10);
	lk2.add(20);
	lk2.add(60);
	lk2.add(40);
	lk2.add(80);
	lk2.cLink2();
	lk2.del();
	lk2.del();
	lk2.del();
	lk2.del();
	lk2.del();
	lk2.cLink2();
	lk2.add(90);
	cout << lk2.size() << endl;
	cout << lk2.getHead() << endl;
	cout << lk2.getTail() << endl;	
	return 0;
}
3. 栈
#ifndef __STACK_H__
#define __STACK_H__
#include <iostream>

template<typename T>
class stack
{
public:
	stack():top(buffer),bottom(buffer),count(0) {}
	T pop();
	T peek();
	void push(T value);	
private:
	bool isEmpty();
	int count;
	T buffer[20];
	T* top;
	T* bottom;
};

template<typename T>
bool stack<T>::isEmpty()
{
	return count==0;
}

template<typename T>
T stack<T>::pop()
{
	if (isEmpty()) {
		std::cout << "data is empty!" << std::endl;
		return 0;
	} else {
		T* temp = top;
		top--;					//当最后一个被pop时,top就越界了,BUG!
		count--;
		return *temp;
	}
}

template<typename T>
void stack<T>::push(T value)
{
	if (count>=20) {
		std::cout << "stack is full!" << std::endl;
	} else {
		top += 1;
		*top = value;
		count++;
	}
}

template<typename T>
T stack<T>::peek()
{
	if (isEmpty()) {
		std::cout << "data is empty!" << std::endl;
		return 0;
	} else {
		return *top;
	}
}

#endif
#include <iostream>
#include "stack.h"

int main(int argc, char** argv)
{
	stack<double> stk;
	stk.peek();
	stk.pop();
	stk.push(1.1);
	stk.push(2.2);
	std::cout << stk.peek() << std::endl;
	std::cout << stk.pop() << std::endl;
	return 0;
}
4. 队列
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <iostream>

template<typename T>
class queue
{
public:
	queue():head(buffer),tail(buffer),empty(true) {}
	T pop();
	void push(T value);
	bool isEmpty();
private:
	T buffer[20];
	bool empty;
	T* head;
	T* tail;
};

template<typename T>
bool queue<T>::isEmpty()
{
	return empty;
}

template<typename T>
T queue<T>::pop()
{
	if(isEmpty()){
		std::cout << "data is empty!" << std::endl;
		return 0;
	} else {
		if(head==tail)
			empty = true;
		return *head;
	}
}

template<typename T>
void queue<T>::push(T value)
{
	if((head+19)==tail) {
		std::cout << "data is full!" << std::endl;
	} else {
		*tail = value;
		if(head!=tail) 
			tail++;
	}
	empty = false;
}

#endif
#include <iostream>
#include "queue.h"

int main(int argc, char** argv)
{
	queue<double> q;
	std::cout << q.pop() << std::endl;
	q.push(1.1);
	std::cout << q.pop() << std::endl;
	std::cout << q.pop() << std::endl;
	q.push(2.2);
	q.push(3.3);
	q.push(4.4);
	std::cout << q.pop() << std::endl;
	return 0;
}
5. 总结
  • 定义在头文件里的模板函数必须在头文件里把方法实现,否则无法编译通过。
  • 通过实际调试程序发现,线性结构实现的关键点不是在结构的中间插入或删除数据的操作上,而是在开头和结尾的地方进行的操作,即在数据结构的边界条件处的操作应该做更严谨的思考,以免出现BUG!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值