//-----------------------day14_AM----------------------------
/*回顾:链表List,遍历
Node* p=head;
while(p!=NULL){
cout<<p->data;
p=p->next;
}
head头指针指向头结点本身不是节点;
输出格式控制:成员函数:width(一次性的,只对下次输出有效),fill,precision,setf/unsetf
格式控制符:endl;flush/setf/setw/setfill/setprecision
文件打开方式:ios::app(追加);open: ofstream fout; fout.open(文件名)等价于ofstream fout(文件名)
is_open()文件是否打开成功;if(fout.is_open)/if(fout)
异常:try{}
throw 数据;
}catch(类型 e){
处理;} catch时先写子类类型的catch,再写父类的catch; catch(...){}
链表:struct Node{ T data; Node* next;};
Node * p=head; 循环 p=p->next; 当p==NULL结束; 创建链表只需要将head=NULL;
增-删-查-改: 新节点插到新节点的前面作为新的头结点;
*/
//双向链表:两个指针,一个指向后一个节点,一个指向前一个指针;赋值的时候需要多给一个指针赋值;
//双向链表会引入尾指针
//线性表: 数组,链表,栈, 队列;
//栈: 只可以在同一端进行插入和删除;[LIFO]->后进先出;可以利用链表或者数组实现栈;
//【栈的实现】
/*
#include<iostream>
using namespace std;
#include<string>
typedef string T;
class List{
struct Node{
T data;
Node* next;
Node(const T&t=T()):data(t)
{ next=NULL;}
};
Node* head;
public:
List():head(NULL){}
void clear(){
while(head!=NULL)
{
Node* q=head->next;
delete head;
head=q;
}
}
~List(){clear();}
void Front_insert(const T &t){
Node* p=new Node(t);
p->next=head;
head=p;
}
void travel(){
Node *p=head;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void insert_back(const T& t){
Node* p=new Node(t);
if(head==NULL)
head=p;
else
getPointer(size()-1)->next=p;
}
int size(){
Node* p=head;
int cnt=0;
while(p!=NULL)
{
cnt++;
p=p->next;
}
return cnt;
}
T getHead(){
if(head==NULL)
throw "no head";
return head->data;
}
T getTail(){
if(head==NULL)
throw "no tail";
Node* p=head;
while(p->next!=NULL)//指针为空则为尾节点
p=p->next;
return p->data;
}
bool empty(){
return head==NULL;
}
int find(const T& t){
Node* p=head;
int pos=0;
while(p!=NULL)
{
if(t==p->data)
return pos;
pos++;
p=p->next;
}
return -1;
}
bool updata(const T&o,const T& n)
{
int pos=find(o);
if(pos==-1)
return false;
Node* p=getPointer(pos);
p->data=n;
return true;
}
private:
Node* getPointer(int pos)
{
Node* p=head;
for(int i=0; i<pos;i++)
p=p->next;
return p;
}
public:
bool erase(const T& t)
{
int pos=find(t);
if(pos==-1)
return false;
if(pos==0)
{
Node* q=head->next;
delete head;
head=q;
}
else{
Node* pre=getPointer(pos-1);
Node* cur=pre->next;
pre->next=cur->next;
delete cur;
}
}
};
class Stack{
List l;//【组合与继承都能实现重用】
public:
void push(const T& t){
l.Front_insert(t);
}//数据入栈
void pop(){
l.erase(l.getHead());
}//删除栈顶元素
T top(){
return l.getHead();
}//取得栈顶元素
bool empty(){
return l.empty();
}//判断栈是否为空;
int size(){
return l.size();
}//取得栈中的元素个数
void clear() {
l.clear();
}
};
int main()
{
Stack s;
s.push("good");
s.push("morning");
s.push("my");
s.push("friend");
while(!s.empty()){
cout<<s.top()<<' ';
s.pop();
}
cout<<endl;
}
*/
//【队列的实现】:必须在不同端进行插入和删除
/*
#include<iostream>
using namespace std;
#include<iomanip>
typedef double T;
class List{
struct Node{
T data;
Node* next;
Node(const T&t=T()):data(t)
{ next=NULL;}
};
Node* head;
public:
List():head(NULL){}
void clear(){
while(head!=NULL)
{
Node* q=head->next;
delete head;
head=q;
}
}
~List(){clear();}
void Front_insert(const T &t){
Node* p=new Node(t);
p->next=head;
head=p;
}
void travel(){
Node *p=head;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void insert_back(const T& t){
Node* p=new Node(t);
if(head==NULL)
head=p;
else
getPointer(size()-1)->next=p;
}
int size(){
Node* p=head;
int cnt=0;
while(p!=NULL)
{
cnt++;
p=p->next;
}
return cnt;
}
T getHead(){
if(head==NULL)
throw "no head";
return head->data;
}
T getTail(){
if(head==NULL)
throw "no tail";
Node* p=head;
while(p->next!=NULL)//指针为空则为尾节点
p=p->next;
return p->data;
}
bool empty(){
return head==NULL;
}
int find(const T& t){
Node* p=head;
int pos=0;
while(p!=NULL)
{
if(t==p->data)
return pos;
pos++;
p=p->next;
}
return -1;
}
bool updata(const T&o,const T& n)
{
int pos=find(o);
if(pos==-1)
return false;
Node* p=getPointer(pos);
p->data=n;
return true;
}
private:
Node* getPointer(int pos)
{
Node* p=head;
for(int i=0; i<pos;i++)
p=p->next;
return p;
}
public:
bool erase(const T& t)
{
int pos=find(t);
if(pos==-1)
return false;
if(pos==0)
{
Node* q=head->next;
delete head;
head=q;
}
else{
Node* pre=getPointer(pos-1);
Node* cur=pre->next;
pre->next=cur->next;
delete cur;
}
}
};
class Queue{
List l;
public:
void push(const T& t){
l.insert_back(t);
}//数据入队
void pop(){
l.erase(l.getHead());
}//删除队首元素
T front(){
return l.getHead();
}//取队首元素
T back(){
return l.getTail();
}//取队尾元素
bool empty(){
return l.empty();
}//判断队列是否为空
int size() {
l.size();
}//取得队列中元素个数
void clear(){
l.clear();
}//清空队列
};
int main()
{
Queue q;
q.push(1.2);
q.push(2.3);
q.push(3.4);
q.push(4.5);
q.push(5.6);
while(!q.empty()){
cout<<setprecision(2)<<fixed<<q.front()<<' ';
q.pop();
}
cout<<endl;
}
*/
/*
#include<iostream>
using namespace std;
typedef int T;
class Stack{
T a[10];
int num;//已经放入的元素个数;
public:
void push(const T& t){
//如果栈中已经放了n个数据,下一个数据应该放在下标是【n】
if(full())
throw "stack overflow";
a[num++]=t;
}
void pop(){
if(empty())
throw "empty stack";
num--;
}
T top(){
if(empty())
throw "no top stack";
return a[num-1];
}
bool empty(){
return num==0;
}
bool full(){
return num==10;
}
int size(){
return num;
}
int capacity(){
return 10;
}
void clear(){
num=0;}
Stack():num(0){}
};
int main()
{
try{
Stack s;
for(int i=0;i<10;i++)
s.push(i+1);
while(!s.empty()){
cout<<s.top()<<' ';
s.pop();
}
cout<<endl;
for(int j=0;j<10;j++)
s.push(i);
cout<<"full?"<<s.full()<<endl;
s.push(100);//this is an exception;
cout<<"can't see this"<<endl;
}catch( const char *){//类型严格匹配
cout<<"unkown exception "<<endl;
}
catch(...){
cout<<" exception "<<endl;
}
}
*/
//利用数组实现队列;
/*
#include<iostream>
using namespace std;
typedef int T;
class Queue{
int num;
T a[10];
public:
Queue():num(0){}
void push(const T&t){
a[num++]=t;
}//插入数据
T front(){
if(empty())
throw "Queue is black";
else
return a[0];
}
void pop(){
for(int i=0;i<9;i++)
{
a[i]=a[i+1];
}
--num;
}//删除数据
bool empty(){
return (num==0);
}//队列是否为空
void clear(){
num=0;
}//清空队列
int size(){
return num;
}//队列数据个数
};
int main()
{
Queue q;
for(int i=0;i<10;i++)
q.push(i);
cout<<"size of queue is:"<<q.size()<<endl;
while(!q.empty()){
cout<<q.front()<<' ';
q.pop();
}
cout<<endl;
for(int j=0;j<10;j++)
q.push(j+1);
// q.push(11);
//q.push(12);
cout<<"this can't be see"<<endl;
}
*/
//-----------------------day_14_pm---坚持,所有的失败归因于半途而废---------------------------
//利用栈实现链表; 两个栈,一个栈倒入到另外一个栈再删除
/*二叉树:BST,二叉查找树,二叉排序树(左子树都应小与父节点,
右子树大于或者等于父节点),二分查找,折半查找;结合了排好序的数组
和链表的优点
struct Node{//二叉在查找树的节点
T data;
Node* left;//指向左子树的根节点
Node* right ;//指向右子树的根节点
Node(const T & t):data(t),left(NULL),right(NULL){}
};
Node* root=NULL;//创建;
void travel(Node* tree)//遍历树:
{
if(tree==NULL) return;//遍历结束标志
else cout<<tree->data<<' ';//先根遍历,前序遍历,【中序遍历】,后序遍历
travel(tree->left);//递归调用,中序遍历用的最多;中序遍历是升序排列数据
travel(tree->right);//递归调用
}
void clear(Node* & tree)//清空树
//不利用引用的话,不会修改原来的跟指针,
//只是复制一份给形参,&分别作为取地址符(&变量), 按位与(n1&n2), (类型&引用名)引用的区别
{
if(tree==NULL) return;
else
{
clear(tree->left);
clear(tree->right);
delete tree;
}
}
int size(Node* tree)// 树的结点个数
{
if(tree==NULL) return 0;
else return size(tree->left)+size(tree->right)+1;//还是递归;
}
//树的高度;
int high(Node* tree)
{
if(tree==NULL) return 0;
else return((high(tree->left)>high(tree->right)?high(tree->left)+1:high(tree->right)+1);
}
}
//增删查
void insert(Node* &tree,Node* p)//插入数据
{
if(tree==NULL) tree=p;
else if(p==NULL) return;
else if((p->data)<(tree->data))
insert(tree->left,p);
else
insert(tree->right,p);
}
Node*& find(Node* &tree,const T &t )//指向该节点的指针;
{
if(tree==NULL) return tree;
else if(tree->data==t) return tree;
else if(t<tree->data)
return find(tree->left,t);
else return find(tree->right,t);
}
// 删除节点,1)合并左右分支2)让指针指向合并后的分支 3)释放要删除的节点;
void erase(Node* &tree, const T t)
{
Node* &p=find(tree,t);
if(p==NULL) return;
else
insert(p->right,p->left);
Node* q=p;
p=p->right;
delete q;
}
//修改节点数据
void updata(const T& o,const T& n)
{
Node* p=find(root,o);
if(p==NULL) return;
erase(root,o);
p=new Node(n);
insert(root,p);
}
//算法: 一组解决某一问题的明确规则;解决问题的步骤和方法;
//算法的几个特征: 又穷性,确切性,输入(0个或多个输入),输出(1个或多个输出),可行性
//f复杂度 complexity(时间time和空间space)
//影响程序可靠性的因素: 野指针, 垃圾数据 ,局部变量的引用,地址,
//使用已经delete的全局变量,越界访问数组;
// 大O表示法;表示计算机的效率,线性查找:O(N) 折半查找O(logN)底数为2;
//常用算法设计策略: 蛮力法、递归技术、分治法(分而制之,体现一分为二的思想)
//模拟法、贪心算法、优化法;
// 每一步的选择最好的;
// 排序法: 选择排序O(N*N) 【冒泡排序O(N*N)】插入排序O(N*N) 快速排序O(N*logN)
*/
//选择排序:每次选择最大或者最小的元素放到相应的位置
//: 1) i从0~N-1;2) 照在下标[i]到下标[n-1]的数据中的最小元素的位置pos
//3)把他好下标为[i]的元素交换;
/*for(int i=0;i<N-1;i++)
{
int t=i,temp;
for(int j=i+1;j<N;j++)
{
if(x[j]>x[t])
t=j;
}
swap(x[i],x[t]);
}*/
/*
#include<iostream>
using namespace std;
#include<ctime>
typedef int T;
void sort(T a[],int n)//(T* a,int n)
{
for(int i=0;i<n-1;i++)
{
int pos=i;
for(int j=i+1;j<n;j++)
{
if(a[j]<a[pos])
pos=j;
}
swap(a[i],a[pos]);
}
}
int main()
{
const long N=102400;
int a[N];
for(int i=0;i<N;i++)
a[i]=N-i;
time_t t1=time(NULL);
sort(a,N);
time_t t2=time(NULL);
for(int j=0;j<20;j++)
cout<<a[j]<<' ';
cout<<endl;
cout<<"time="<<t2-t1<<endl;
}
*/
-line-h� #Gta~@�Y7> Node* p=getPointer(pos);
p->data=n;
return true;
}
private:
Node* getPointer(int pos)
{
Node* p=head;
for(int i=0; i<pos;i++)
p=p->next;
return p;
}
public:
bool erase(const T& t)
{
int pos=find(t);
if(pos==-1)
return false;
if(pos==0)
{
Node* q=head->next;
delete head;
head=q;
}
else{
Node* pre=getPointer(pos-1);
Node* cur=pre->next;
pre->next=cur->next;
delete cur;
}
}
};
int main()
{
List obj;
obj.Front_insert(1);
obj.Front_insert(2);
obj.Front_insert(3);
obj.Front_insert(4);
obj.Front_insert(5);
cout<<"size:"<<obj.size()<<endl;
obj.travel();
cout<<"find 3:"<<obj.find(3)<<endl;
cout<<"find 8:"<<obj.find(8)<<endl;
obj.updata(4,100);
obj.travel();
obj.erase(3);
obj.erase(5);
obj.erase(1);
obj.erase(2);
obj.travel();
obj.insert_back(7);
obj.insert_back(8);
obj.insert_back(9);
obj.insert_back(10);
obj.travel();
}