数据结构及STL.docx

上传人:b****6 文档编号:8590327 上传时间:2023-02-01 格式:DOCX 页数:81 大小:40.72KB
下载 相关 举报
数据结构及STL.docx_第1页
第1页 / 共81页
数据结构及STL.docx_第2页
第2页 / 共81页
数据结构及STL.docx_第3页
第3页 / 共81页
数据结构及STL.docx_第4页
第4页 / 共81页
数据结构及STL.docx_第5页
第5页 / 共81页
点击查看更多>>
下载资源
资源描述

数据结构及STL.docx

《数据结构及STL.docx》由会员分享,可在线阅读,更多相关《数据结构及STL.docx(81页珍藏版)》请在冰豆网上搜索。

数据结构及STL.docx

数据结构及STL

数据结构

******************

day09

******************

第一课堆栈与队列

1、数据结构的基本概念

(1)逻辑结构

1)集合结构(集):

结构中的元素除了同属一个集外,没有任何联系

2)线性结构(表):

结构中的元素具有一对一的前后关系

3)树型结构(树):

结构中的元素具有一对多的父子关系

4)网状结构(图):

结构中的元素具有多对多的交叉映射关系

(2)物理结构

1)顺序结构(数组):

结构中的元素存放在一段连续的地址空间中。

随机访问方便,空间利用率低,插入删除不方便

2)链式结构(链式):

结构中的元素存放在彼此独立的地址空间中,每个独立的地址空间叫节点。

节点中除了保存数据以外还保存另外一个或几个相关节点的地址。

空间利用率高,插入删除方便,随机访问不方便

(3)逻辑结构和物理结构的关系

表树图

顺序数组顺序树复

链式链表链式树合

2、数据结构的基本运算

(1)创建与销毁

(2)插入与删除

(3)获取与修改

(4)排序与查找

3、堆栈(vistatic.cpp/lstatic.cpp)

(1)基本特征:

后进先出

(2)基本操作:

压入(push),弹出(pop)

(3)实现要点:

初始化空间,栈顶指针,判空判满

【代码:

vistack.cpp】

#include

usingnamespacestd;

//基于顺序表的堆栈

classStack{

public:

//构造过程中分配内存

Stack(size_tsize=10):

m_array(newint[size]),m_size(size),

m_top(0){}

//析构过程中释放内存

~Stack(void){

if(m_array){

delete[]m_array;

m_array=0;

}

}

//压入

voidpush(intdata){

if(full())

throwOverFlow();

m_array[m_top++]=data;

}

//弹出

intpop(void){

if(empty())

throwUnderFlow();

returnm_array[--m_top];

}

//判满

boolfull(void)const{

returnm_top>=m_size;

}

//判空

boolempty(void)const{

return!

m_top;

}

private:

//上溢异常

classOverFlow:

publicexception{

constchar*what(void)constthrow(){

return"堆栈上溢!

";

}

};

//下溢异常

classUnderFlow:

publicexception{

constchar*what(void)constthrow(){

return"堆栈下溢!

";

}

};

int*m_array;//数组

size_tm_size;//容量

size_tm_top;//栈顶

};

voidprintb(unsignedintnumb,intbase){

Stackstack(256);

do{

stack.push(numb%base);

}while(numb/=base);

while(!

stack.empty()){

intdigit=stack.pop();

if(digit<10)

cout<

else

cout<

}

cout<

}

intmain(void){

try{

Stackstack;

for(inti=0;!

stack.full();++i)

stack.push(i);

//stack.push(0);

while(!

stack.empty())

cout<

//stack.pop();

}

catch(exception&ex){

cout<

return-1;

}

cout<<"输入一个整数:

"<

intnumb;

cin>>numb;

cout<<"您想看几进制:

"<

intbase;

cin>>base;

cout<<"结果:

";

printb(numb,base);

return0;

}

【代码:

vilstack.cpp】

#include

usingnamespacestd;

//基于链式表的堆栈

classStack{

public:

//构造过程中初始化为空堆栈

Stack(void):

m_top(NULL){}

//析构过程中销毁剩余的节点

~Stack(void){

for(Node*next;m_top;m_top=next){

next=m_top->m_next;

deletem_top;

}

}

//压入

voidpush(intdata){

/*

Node*node=newNode;

node->m_data=data;

node->m_next=m_top;

m_top=node;*/

m_top=newNode(data,m_top);

}

//弹出

intpop(void){

if(empty())

throwUnjjderFlow();

intdata=m_top->m_data;

Node*next=m_top->m_next;

deletem_top;

m_top=next;

returndata;

}

//判空

boolempty(void)const{

return!

m_top;

}

private:

//下溢异常

classUnderFlow:

publicexception{

constchar*what(void)constthrow(){

return"堆栈下溢!

";

}

};

//节点

classNode{

public:

Node(intdata=0,Node*next=NULL):

m_data(data),m_next(next){}

intm_data;//数据

Node*m_next;//后指针

};

Node*m_top;//栈顶

};

intmain(void){

try{

Stackstack;

for(inti=0;i<10;++i)

stack.push(i);

while(!

stack.empty())

cout<

//stack.pop();

}

catch(exception&ex){

cout<

return-1;

}

return0;

}

***********************************************************

4、队列(viq.cpp/q1.cpp)

(1)基本特征:

先进先出

(2)基本操作:

压入(push),弹出(pop)

(3)实现要点:

初始化空间,从前端(front)弹出,从后端(rear)压入,循环使用,判空判满

【代码:

viq.cpp】

#include

#include"lstack.h"

usingnamespacestd;

//基于堆栈的队列

classQueue{

public:

//压入

voidpush(intdata){

m_i.push(data);

}

//弹出

intpop(void){

if(m_o.empty()){

if(m_i.empty())

throwunderflow_error("队列下溢!

");

while(!

m_i.empty())

m_o.push(m_i.pop());

}

returnm_o.pop();

}

//判空

boolempty(void)const{

returnm_i.empty()&&m_o.empty();

}

private:

Stackm_i;//输入栈

Stackm_o;//输出栈

};

intmain(void){

try{

Queuequeue;

for(inti=0;i<10;++i)

queue.push(i);

cout<

cout<

cout<

cout<

cout<

queue.push(10);

queue.push(11);

queue.push(12);

while(!

queue.empty())

cout<

}

catch(exception&ex){

cout<

return-1;

}

return0;

}

【代码:

viq1.cpp】

#include

usingnamespacestd;

//基于顺序表的队列

classQueue{

public:

//构造过程中分配内存

Queue(size_tsize=5):

m_array(newint[size]),m_size(size),

m_rear(0),m_font(0),m_count(0){}

~Queue(void){

if(m_array){

delete[]m_array;

m_array=NULL;

}

}

//压入

voidpush(intdata){

if(full())

throwoverflow();

if(m_rear>=m_size)

m_rear=0;

++m_count;

m_array[m_rear++]=data;

}

//弹出

intpop(void){

if(empty())

throwunderflow();

if(m_font>=m_size)

m_font=0;

--m_count;

returnm_array[m_font++];

}

//判空

boolempty()const{

return!

m_count;

}

//判满

boolfull(){

returnm_count==m_size;

}

private:

//上溢异常

classoverflow:

publicexception{

constchar*what(void)constthrow(){

return"队列上溢!

";

}

};

//下溢异常

classunderflow:

publicexception{

constchar*what(void)constthrow(){

return"队列下溢!

";

}

};

int*m_array;

size_tm_size;//容量

size_tm_rear;

size_tm_font;

size_tm_count;

};

intmain()

{

try{

Queuequeue;

queue.push(10);

queue.push(20);

queue.push(30);

queue.push(40);

queue.push(50);

//queue.push(60);

cout<

queue.push(60);

cout<

queue.push(70);

cout<

cout<

cout<

cout<

}

catch(exception&ex){

cout<

return-1;

}

return0;

}

【思考题:

如何用堆栈来实现队列?

(vilstatic2.cpp)】

#include//用堆栈来实现队列

#include"lstatic.h"

usingnamespacestd;

classQueue{

public:

//压入

voidpush(intdata){

m_i.push(data);

}

//弹出

intpop(){

if(m_o.empty()){

if(m_i.empty())

throwunderflow_error("队列下溢!

");

while(!

m_i.empty())

m_o.push(m_i.pop());

}

returnm_o.pop();

}

//判空

boolempty()const{

returnm_i.empty()&&m_o.empty();

}

private:

stackm_i;//输入栈

stackm_o;//输出栈

};

intmain()

{

try{

Queuequeue;

for(inti=0;i<10;++i)

queue.push(i);

cout<

cout<

cout<

cout<

cout<

cout<

}

catch(exception&ex){

cout<

}

}

5、链表

(1)基本特征:

内存中不连续的节点序列,彼此之间通过指针相互关联,前指针(prev)指向前节点,后指针(next)指向后节点

(2)基本特征:

追加、插入、删除、遍历

(3)实现要点:

void讲故事(void){

从前有座山;

山里有个庙;

庙里有个老和尚;

if(老和尚圆寂了)

return;

讲故事();

}

6、二叉树(vibstree.cpp)

(1)基本特征

1)树型结构的最简模型,每个节点最多有两个子节点

2)单根,除根节点外每个节点有且只有一个父节点,整棵树只有一个根节点

3)递归结构,用递归处理二叉树问题可以简化算法

(2)基本操作

1)生成

2)遍历

D-L-R:

前序遍历L-D-R:

中序遍历L-R-D:

后序遍历

有序二叉树(二叉搜索树):

L<=D<=R(左小右大)

507020604030109080

50

/\

/----\

20|70

/\/\

10406090

//

3080

/

10

中序遍历:

102030405060708090

【代码:

vibstree.cpp】

include

usingnamespacestd;

//有序二叉树(搜索二叉树)

classTree{

public:

//构造函数过程中初始化为空树

Tree(void):

m_root(NULL),m_size(0){}

//析构过程中销毁剩余节点

~Tree(void){

clear();

}

//插入数据

voidinsert(intdate){

insert(newNode(date),m_root);

++m_size;

}

//删除第一个匹配的数据,不存在返回false

boolerase(intdate){

Node*&node=find(date,m_root);

if(node){

//左子树插入右子树

insert(node->m_left,node->m_right);

Node*temp=node;

//右提升

node=node->m_right;

deletetemp;

--m_size;

returntrue;

}

returnfalse;

}

//删除所有匹配数据

voidremove(intdate){

while(erase(date));

}

//清空树

voidclear(void){

clear(m_root);

m_size=0;

}

//将所有的_old替换为_new

voidupdate(int_old,int_new){

while(erase(_old))

insert(_new);

}

//判断date是否存在

boolfind(intdate){

returnfind(date,m_root)!

=NULL;

}

//中序遍历

voidtravel(){

travel(m_root);

cout<

}

//获取树高

size_theight(){

returnheight(m_root);

}

//获取大小

size_tsize(void){

returnm_size;

}

private:

//节点

classNode{

public:

Node(intdate):

m_date(date),m_left(NULL),m_right(NULL){}

intm_date;//数据

Node*m_left;//左树

Node*m_right;//右树

};

voidinsert(Node*node,Node*&tree){

if(!

tree)

tree=node;

elseif(node){

if(node->m_datem_date)

insert(node,tree->m_left);

else

insert(node,tree->m_right);

}

}

//返回子树tree中值与date相匹配的节点的父节中指向该节点的成员变量的别名

Node*&find(intdate,Node*&tree){

if(!

tree)

returntree;

else

if(date==tree->m_date)

returntree;

else

if(datem_date)

returnfind(date,tree->m_left);

else

returnfind(date,tree->m_right);

}

voidclear(Node*&tree){

if(tree){

clear(tree->m_left);

clear(tree->m_right);

deletetree;

tree=NULL;

}

}

voidtravel(Node*tree){

if(tree){

travel(tree->m_left);

cout<m_date<<'';

travel(tree->m_right);

}

}

size_theight(Node*tree){

if(tree){

size_tlh=height(tree->m_left);

size_trh=height(tree->m_right);

return(lh>rh?

lh:

rh)+1;

}

return0;

}

Node*m_root;//树根

size_tm_size;//大小

};

intmain()

{

Treetree;

tree.insert(50);

tree.insert(70);

tree.insert(20);

tree.insert(60);

tree.insert(40);

tree.insert(30);

tree.insert(10);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1