文章目录
1 栈
栈顶指针:始终指向栈顶元素的标记,数组栈的栈顶指针通常记为TOP,空栈通常令TOP = -1;
int size(){
return TOP+1;//数组下标从零开始
}
bool empty(){
if(TOP==1) return true;
else return false;
}
void push(int x){
st[++TOP]=x;
}
void pop(){
TOP--;
}
int top(){
return st[TOP];
}
以上都可以使用STL实现
使用pop函数和top函数前一定要先判空
STL没有实现栈的清空功能
while(!st.empty()){
st.pop();
}
但事实上,更常用的是重新定义一个栈变相实现栈的清空
2 队列
队首指针front——指向队首元素的前一个位置
队尾指针rear——指向队尾元素
初始状态:front = -1 ; rear = -1
void clear(){
front = rear =-1;
}
int size(){
return rear-front;
}
bool empty(){
if(front == rear) return true;
else return false;
}
void push(x){
q[++rear]=x;
}
void pop(){
front++;
}
int front(){
return q[front+1];
}
int back(){
return q[rear];
}
以上函数都可以使用STL
while(!q.empty()){
q.pop();
}
3 链表
struct node{
typename data;
node* next;
};
分配内存空间
3.1 内存空间的分配
3.1.1 C语言中的malloc与free函数
malloc函数向内存申请一块大小为sizeof(node)的空间,并返回指向这块空间的未确定类型的指针,再强制转换类型并赋值;当申请失败时(一般发生再申请了较大的动态数组),返回空指针NULL并赋值给p
#include<cstdlib>
返回类型未申请的同变量类型的指针
typename* p = (typename*)malloc(sizeof(typename));
int* p = (int*)malloc(2*sizeof(int));
node* p = (node*)malloc(sizeof(node));
free(p);
free函数实现了两个效果:
1)释放指针变量p指向的内存空间
2) 将指针变量p指向空地址NULL
即free函数执行后,p本身并没有消失
3.1.2 C++中的new与delete运算符
返回对应类型的指针,申请失败(申请了较大的动态数组)会启动C++异常机制处理而不是返回空指针NULL
typename* p = new typename;
int* p = new int;
node* p = new node;
delete(p);
3.1.3 内存泄漏
指用malloc和new开辟出来的内存空间在使用过后没有释放,导致其在程序结束之前始终占据该内存空间,导致最后无内存可分配,故以上函数必须成对出现避免内存泄漏
3.2 链表的基本操作
3.2.1 创建
#include<cstdio>
struct node{
int data;
node* next;
};
node* create(int array[]){
node *p,*pre,*head; 定义当前结点、前驱结点、投加顶啊
head = new node; 创建头结点
head->next = NULL; 头节点指针域为空
pre = head; 建立链表前,头节点作为前驱结点
for(int i=0;i<5;i++){
p = new node; 新建结点
p->data =array[i];
p->next = NULL;
pre->next=p; 前驱结点指针域更新
pre=p; 当前节点作为前驱结点
}
return head;
}
int main(){
int array[5] = {5,3,6,1,2};
node* L = create(array);
L = L->next; 从第一个结点开始有数据
while(L!=NULL){
printf("%d",L->data);
L=L->next;
}
return 0;
}
3.2.2 查找
int search(node* head,int x){
int count = 0;
node* p = head->next;
while(p!=NULL){
if(p->data == x){
count++;
}
p = p->next;
}
return count; 返回链表中元素x的个数
}
3.2.3 插入
void insert(node* head,int pos,int x){
node* p=head;
for(int i=0;i<pos-1;i++){
p=p->next;
注意:为了到插入位置的前一个结点
是通过前前个结点的下一个来获取到的
}
node* q=new node;
q->data = x;
q->next =p->next;
p->next =q;
}
3.2.4 删除(略)
3.3 静态链表
当结点的地址是比较小的整数,例如五位数的地址,就没必要去建立动态链表,使用方便的静态链表
实现原理:hash,通过建立一个结构体数组,并令数组的下标直接表示结点的地址,来达到直接访问数组中的元素就能访问结点的效果,并且不需要头节点
struct Node{
typename data;
int next;
}node[size];
node[11111]=22222;
node[22222]=33333;
node[33333]=-1;
由于静态链表由数组实现,可能会对其进行排序,故结构体类型名和结构体变量名尽量不要相同