机器感知 一个专注于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!