1)队列
2)链表
3)栈
首先:
你要明白c++指针的含义,它仅指向一个元素,如果你要找到它的下一个元素:p=p->next;【这也是为什么链表查找元素是O(n),而数组是O(1)】;
因为指针这个特点,你在写链表,如果采取尾插法,但是没有尾指针,那每次插入就特别麻烦了,需要从头遍历,找到尾巴,再插入。【这也是为什么栈只需要一个top指针即可,因为栈只在一端进行操作,而队列需要一个head和一个tail指针,因为它要在两端操作】
一·队列
我的误区:
像队列这种线性结构:它们应该包含两个部分:一个是结点node再一个就是队列queue本身
源代码:
#include<iostream>
#define null NULL
using namespace std;
template<class T>
class node {
public:
T elem;
node* next;
node(){}
node(T elem) {
this->elem = elem;
this->next = null;
}
};
template<class T>
class my_Queue {
private:
node<T>* head;
node<T>* tail;
public:
my_Queue() {
this->head = new node<T>();
this->tail = new node<T>();
}
void Enqueue(T elem) {
node<T>* temp = new node<T>(elem);
if (head->next == null) {//队列为空
head->next = temp;
tail = temp;
}
else {
tail->next = temp;
tail = temp;
}
}
T Dequeue() {
T data;
if (head != null)data = head->next->elem;
else return null;
head = head->next;
return data;
}
T Gethead() {
if (head->next != null)return head->next->elem;
else return null;
}
bool IsEmpty() {
return head->next != null ? true : false;
}
};
int main() {
my_Queue<int>* Queue_pin = new my_Queue<int>();
Queue_pin->Enqueue(1);
Queue_pin->Enqueue(2);
Queue_pin->Enqueue(3);
while (Queue_pin->IsEmpty()) {
cout << Queue_pin->Dequeue() << endl;
}
return 0;
}
二 链表(同队列没啥大区别)
#include<iostream>
#define null NULL
using namespace std;
template<class T>
class ListNode {
public:
T elem;
ListNode* next;
ListNode(){}
ListNode(T elem) {
this->elem = elem;
this->next = null;
}
};
template<class T>
class my_List {
ListNode<T>* head;
ListNode<T>* tail;
public:
my_List() {
head = new ListNode<T>();
tail = new ListNode<T>();
}
void head_add(T elem) {
ListNode<T>* temp = new ListNode<T>(elem);//头插法,tail指针就没用了
if (head->next == null) {
head->next = temp;
}
else {
temp->next = head->next;
head->next = temp;
}
}
void tail_add(T elem) {
ListNode<T>* temp = new ListNode<T>(elem);
if (head->next == null) {//含有头结点,即head本身只是个结点,不含实际数据
head->next = temp;//尾插法须有tail,不然每插入都得从头遍历,时间达到O(n)
tail = temp;
}
else {
tail->next = temp;
tail = temp;
}
}
};
int main() {
my_List<int>* chain = new my_List<int>();
chain->tail_add(1);
chain->tail_add(2);
chain->tail_add(3);
chain->head_add(1);
chain->head_add(2);
chain->head_add(3);
return 0;
}
三·栈(同上)
#include<iostream>
#define null NULL
using namespace std;
template<class T>
class node {
public:
T elem;
node* next;
node(){}
node(T elem) {
this->elem = elem;
this->next = null;
}
};
template<class T>
class my_Stack {
node<T>* top;
public:
my_Stack() {
top = new node<T>();
}
void push(T elem) {
node<T>* temp = new node<T>(elem);
if (top->next == null) {//栈为空
top->next = temp;
}
else {
temp->next = top->next;
top->next = temp;
}
}
T pop() {
T data;
if (top->next != null)data = top->next->elem;
else data = null;
top = top->next;
return data;
}
T gettop() {
return top->next->elem;
}
bool IsEmpty() {
return this->top != null ? true : false;
}
void destory(my_Stack *&primary) {
delete primary;
primary = null;
}
};
int main(){
my_Stack<int> *stack_pin=new my_Stack<int>();
stack_pin->push(1);
stack_pin->push(2);
stack_pin->push(3);
while (stack_pin->IsEmpty()) {
cout <<stack_pin->pop() << endl;
}
return 0;
}
/*
之前的“错误”版本:
#include<iostream>
#include<string.h>
#include<stack>
using namespace std;
class my_Stack {
int id;
my_Stack* next;
public:
my_Stack(int id) {
this->id = id;
this->next = NULL;
}
my_Stack() {
this->id = NULL;
this->next = NULL;
}
void destory(my_Stack*& primary) {
delete primary;
primary = NULL;
}
void push(int id,my_Stack *& primary) {
//my_Stack *& primary ,引用传递,实现对栈的修改
my_Stack *temp = new my_Stack(id);
temp->next = primary;
primary = temp;
}
int pop(my_Stack *& primary) {
int temp = primary->id;
primary = primary->next;
return temp;
}
int gettop(my_Stack* primary) {
return primary->id;
}
};
int main() {
my_Stack *pin=new my_Stack();
stack<int>*p =new stack<int>();
p->push(1);
p->push(2);
pin->push(1,pin);
//与c++自带的stack最大的区别在与,需要额外传递一个pin指针,【否则做不到对pin的直接修改】
//至于自带的stack怎么实现不用传pin的,还没搞懂,源代码没太看明白
pin->push(2, pin);
pin->push(3, pin);
//pin->destory(pin);
while (pin != NULL) {
cout << pin->pop(pin) << endl;
}
return 0;
}
*/