数据结构课程期末总结一
实验一:
编写C++顺序表类,利用顺序存储结构存储数据,并实现其相应功能。
功能1:完成顺序表的初始化。
功能2:实现顺序表的置空功能。
功能3:实现顺序表的输入功能。
功能4:求顺序表中第i个元素,要求返回第i个元素是否存在的结果,并返回第i个元素值,利用如下的函数形式实现:
bool get_Element(int i, element_Type & data)
功能5:在第i个结点前插入值为x的结点。
功能6:删除顺序表中第i个元素结点,需返回第i个是否存在的状态,并返回删除值。
功能7:检查顺序表中是否有重复的元素,若有,则删除重复的元素,该功能要求能返回是否重复的结果,并将删除元素返回。
#include<math.h> #include<stdio.h> #include<iostream> #include<malloc.h> #include<string.h> #include<stdlib.h> #define elemtype int #define max 100 using namespace std; class donserlist { private: elemtype donser[max]; elemtype length; public: void start_list(donserlist &l);//初始化 void put_null(donserlist &l);//置空 void get_num(donserlist &l);//输入数据 int get_Element(donserlist &l,int i);//查找位置并返回 void insert_num(donserlist &l,int num,int i);//插入数据 void delete_num(donserlist &l,int i);//删除数据 void check_re(donserlist &l);//检查是否重复 void go_see(donserlist &l);//遍历输出 };
#include"head.h" void donserlist::start_list(donserlist &l) { l.length=0; } void donserlist::put_null(donserlist &l) { int i=l.length; if(i==0){printf("NULL!\n");} for(int j=1;j<=i;j++) { l.donser[j]=0; } } void donserlist::get_num(donserlist &l) { int a; cout<<"输入几个数?\n"; scanf("%d",&a); l.length=a; cout<<"输入这些数!\n"; for(int i=1;i<=a;i++) { scanf("%d",&l.donser[i]); } cout<<"存储完毕\n"; } int donserlist::get_Element(donserlist &l,int i) { int a=l.length; if(i<1||i>a){printf("wrong!\n");} cout<<l.donser[i]<<endl; return 0; } void donserlist::insert_num(donserlist &l,int num,int i) { int a=l.length; if(a>=max) {exit(0);} for(int j=a+1;j>i;j--) { l.donser[j]=l.donser[j-1]; } l.donser[i]=num; l.length++; } void donserlist::delete_num(donserlist &l,int i) { int a=l.length; if(i>a||i<1) {exit(0);} for(int j=i;j<=a;j++) { l.donser[j]=l.donser[j+1]; } l.length--; } void donserlist::check_re(donserlist &l) { int a=l.length; int b=1,now=0,code=3; bool china=true; cout<<"检查重复元素: "; while(b<=a) { b++; now=l.donser[b]; for(int j=b+1;j<=a;j++) { if(l.donser[j]==now) { cout<<now<<" "; code=1; china=false; l.length--; } if(code==1){delete_num(l,j);a--;code=3;} } code=3; } if(china){cout<<"无重复!\n";} else cout<<endl; } void donserlist::go_see(donserlist &l) { //cout<<"*"<<l.length<<"*"<<endl; for(int i=1;i<=l.length;i++) { cout<<l.donser[i]<<" "; } cout<<endl; }
#include"head.h" int main() { int tt,nn; donserlist d; cout<<"1.现在已经初始化\n"; d.start_list(d); d.go_see(d); cout<<"2.顺序表已经置空\n"; d.put_null(d); d.go_see(d); cout<<"3.顺序表输入\n"; d.get_num(d); d.go_see(d); cout<<"4.输入要找的某个元素的位置\n"; scanf("%d",&tt); d.get_Element(d,tt); d.go_see(d); cout<<"5.输入要插入的数据及位置\n"; scanf("%d%d",&tt,&nn); d.insert_num(d,tt,nn); d.go_see(d); cout<<"6.要删除的数据位置\n"; scanf("%d",&tt); d.delete_num(d,tt); d.go_see(d); cout<<"7.检查数据是否重复\n"; d.check_re(d); d.go_see(d); return 0; }
实验二
编写C++单链表类,实现其相应功能
功能1:在构造函数完成带头结点单链表的初始化。
功能2:输入数据,利用尾插法完成链表生成。
功能3:利用断点功能,查看已经存入的结点数据,并截图说明。
功能4:求单链表表长。
功能5:求链表中第i个元素,要求返回第i个元素是否存在的结果,并返回第i个元素值及其结点地址。
功能5:在第i个结点前插入值为x的结点。
功能6:删除链表中第i个元素结点,需返回第i个结点是否存在的状态,并返回删除结点中存储的数据。
功能7:在析构函数中完成链表内存释放,声明一个对象,截图描述并说明其构造函数、析构函数调用顺序及过程。
#ifndef donser_list #define donser_list #include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> //#define NULL 0 using namespace std; struct donser { int data; donser* next; }; class list { donser* head; public: list(){head=NULL;} //头结点单链表的初始化 void listinsert(int i);//尾插法完成链表生成 void coutlist();//查看当前链表 void seelength();//求单链表表长 int findlist(int i);//求链表中第i个元素 int insertnum(int i,int x);//在第i个结点前插入值为x的结点 int deletenum(int i);//删除链表中第i个元素结点 ~list();//在析构函数中完成链表内存释放 }; #endif
#include"head.h" void list::listinsert(int i) { int x,j; j=i; donser*u; donser*r; donser*l; l=new donser; r=l; scanf("%d",&x); while(1) { j--; u=new donser; u->data=x; if(j==i-1){head=u;} u->next=NULL; r->next=u; r=u; if(j==0){break;} scanf("%d",&x); } } void list::coutlist() { donser *a; a=head; //cout<<"*"; //cout<<&head<<" "<<a->next; cout<<"当前序列:"; while(a->next!=NULL) { cout<<a->data<<" "; a=a->next; } cout<<a->data<<" "; cout<<endl; } void list::seelength() { donser *a; int i=1; a=head; while(a->next!=NULL) { a=a->next; i++; } cout<<"长度为:"<<i<<endl; } int list::findlist(int i) { donser *a; int j=1; a=head; if(i==1){cout<<"找到:位置1"<<"元素为:"<<a->data<<"结点地址:"<<&a<<endl;return 0;} while(1) { a=a->next; j++; if(i==j){break;} if(a->next==NULL) {cout<<"不存在\n";return 0;} } cout<<"找到:位置"<<i<<"元素为:"<<a->data<<"结点地址:"<<&a<<endl; return 0; } int list::insertnum(int i,int x) { donser *p,*l,*s; p=head; int k=1; if(i==1) { s=new donser; s->data=x; s->next=head; head=s; cout<<"已插入\n"; return 0; } while(k!=i-1&&p!=NULL) { p=p->next; k++; } if(p==NULL) { cout<<"不存在\n"; return 0; } if(p->next==NULL) { s=new donser; s->data=x; s->next=NULL; p->next=s; cout<<"已插入\n"; return 0; } else { s=new donser; s->data=x; //p->next->data=s->data; s->next=p->next; p->next=s; cout<<"已插入\n"; //cout<<x<<" "<<p->data<<" "<<p->next->data<<" "<<p->next->next->data<<" "<<p->next->next->next->data<<endl; return 0; } } int list::deletenum(int i) { donser *l,*u,*p; p=head; i--; int k=0; if(i==0) { head=p->next; return 0; } while(k!=i-1&&p!=NULL) { p=p->next; k++; } cout<<p->data<<" "<<p->next->data<<endl; if(p==NULL||p->next==NULL) {cout<<"不存在\n";return 0;} if(p->next->next==NULL) { u=p->next; p->next=NULL; delete u; cout<<"已删除\n"; return 0; } else { u=p->next; p->next=u->next; delete u; cout<<"已删除\n"; return 0; } } list::~list() { donser *a; while(head!=NULL) { a=head; head=a->next; delete a; } }
#include"head.h" int main() { int i,j,k,m,n; list a; cout<<"1:构造函数完成带头结点单链表的初始化\n"; //a.list(); cout<<"已初始化\n"; cout<<"2:输入数据,利用尾插法完成链表生成\n"; cout<<"输入要插入几个数据\n"; scanf("%d",&m); a.listinsert(m); cout<<"3:查看已经存入的结点数据\n"; a.coutlist(); cout<<"4:求单链表表长\n"; a.seelength(); cout<<"5:求链表中第i个元素\n"; cout<<"输入i:"; scanf("%d",&n); a.findlist(n); cout<<"6:在第i个结点前插入值为x的结点\n"; cout<<"输入i,x:"; scanf("%d%d",&i,&j); a.insertnum(i,j); a.coutlist(); //system("pause"); cout<<"7:删除链表中第i个元素结点\n"; cout<<"输入i:"; scanf("%d",&k); a.deletenum(k); a.coutlist(); cout<<"8:在析构函数中完成链表内存释放\n"; a.~list(); cout<<"已释放\n"; system("pause"); return 0; }
实验三
熟练双链表使用,利用链式存储结构实现相应数据结构
功能1:初始化双链表
功能2:输入数据
功能3:求表长
功能4:删除第i个节点
功能5:检查双链表是否对称,输入多个数据进行验证
功能6:其他功能自行编写,验收时讲解给老师即可
#include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; struct donser { int data; donser* last; donser* next; }; int dongser; class list { donser* head; donser* tmp; donser* now; donser* rec; public: list(); //头结点链表的初始化 void listinsert(int i); //完成链表生成 void coutlist(); //查看当前链表 void seelength(); //求链表表长 int deletenum(int i); //删除链表中第i个元素结点 int checkABA(); //检查对称 ~list(); //在析构函数中完成链表内存释放 }; //#include"head.h" list::list() { donser *a; a=new donser; a->data=0; a->next=a; a->last=a; cout<<"————已初始化\n"; } void list::listinsert(int i) { int x,y=0; donser*a; donser*b; donser*c; a=new donser; c=new donser; scanf("%d",&x); c->data=x; tmp=now=c; a=c; while(i--) { scanf("%d",&x); b=new donser; b->data=x; a->next=b; b->last=a; c->last=b; if(y==0){c->next=a->next;i--;} a=b; y=1; } b->next=c; head=c; } void list::coutlist() { donser *a; a=head; cout<<"————当前序列:"; while(a->next!=tmp) { cout<<a->data<<" "; a=a->next; } cout<<a->data<<" "; cout<<endl; } void list::seelength() { donser *a; int i=1; a=head; while(a->next!=tmp) { a=a->next; i++; } dongser=i; cout<<"————长度为:"<<i<<endl; } int list::deletenum(int i) { donser *l,*u,*p; p=head; i--; int k=1; if(i==0) { head=p->next; return 0; } while(k<i&&p->next!=tmp) { p=p->next; k++; } if(i>=dongser) {cout<<"————不存在\n";return 0;} else { l=p->next->next; u=p->next; p->next=u->next; l->last=p; delete u; cout<<"————已删除\n"; return 0; } } int list::checkABA()//now rec { donser*a; a=head; now=rec=tmp; now=a; rec=a->last; while(now->next!=rec->last) { if(now->data!=rec->data) { cout<<"————不对称!\n";return 0; } now=now->next; rec=rec->last; if(dongser--){break;} } cout<<"————对称表!\n";return 1; } list::~list() { donser *a; while(head!=tmp) { a=head; head=a->next; delete a; } } //#include"head.h" int main() { int k,m; cout<<"**构造函数完成双链表的初始化\n"; list a; cout<<"**输入数据,完成链表生成\n"; cout<<"————输入要插入几个数据\n"; scanf("%d",&m); a.listinsert(m); cout<<"**查看已经存入的结点数据\n"; a.coutlist(); cout<<"*求链表表长\n"; a.seelength(); cout<<"**删除链表中第i个元素结点\n"; cout<<"————输入i:"; scanf("%d",&k); a.deletenum(k); a.coutlist(); cout<<"**检查对称\n"; a.checkABA(); cout<<"**附加功能:已经是双向循环链表\n"; cout<<"**在析构函数中完成链表内存释放\n"; a.~list(); cout<<"————已释放\n"; system("pause"); return 0; }
实验四
利用所编写的栈类,实现下列应用。
(1)十进制数转换为八进制数。
(2)利用栈实现12+5*(2+3)*6/2-4 的求解
(3)利用栈解决迷宫问题:一个迷宫的实例,如右图所示:
图中紫色方块为障碍,不能通行;白色方块可以通行;需求出从入口到出口的一条通道
#include<cstdio> #include<string.h> #include<stdlib.h> #include<iostream> #define max 100 using namespace std;//push(i) pop() top() empty() class a_stack { private: int donser[max]; int length=0; public: void push_num(a_stack &l,int i);//入栈push void pop_num(a_stack &l);//出栈pop int top_num(a_stack &l);//返回栈顶数据top int check_empty(a_stack &l);//检查是否为空empty }; void a_stack::push_num(a_stack &l,int i) { int k; l.length++; k=l.length; l.donser[k]=i; } void a_stack::pop_num(a_stack &l) { int k; k=l.length; l.length--; l.donser[k]=0; } int a_stack::top_num(a_stack &l) { return l.donser[l.length]; } int a_stack::check_empty(a_stack &l)//1为空 { if(l.length==0){return 1;} else return 0; } int main() { int i=0,j,a,b; a_stack s; cout<<"输入十进制\n"; scanf("%d",&a); while(1) { b=a%8; a=a/8; s.push_num(s,b); if(a==0){break;} } while(1) { if(s.check_empty(s)==1){break;} j=s.top_num(s); s.pop_num(s); i=i*10+j; } cout<<"八进制:"<<endl; cout<<i<<endl; return 0; }
#include<iostream> #include<math.h> #include<stdio.h> #include<malloc.h> #include<string.h> #include<stdlib.h> #define max 100 using namespace std;//push(i) pop() top() empty() class a_stack { private: double donser[max]; int length=0; public: void push_num(a_stack &l,double i);//入栈push void pop_num(a_stack &l);//出栈pop double top_num(a_stack &l);//返回栈顶数据top int check_empty(a_stack &l);//检查是否为空empty }; class b_stack { private: char donser1[max]; int length1=0; public: void push_num(b_stack &l,char i);//入栈push void pop_num(b_stack &l);//出栈pop int top_num(b_stack &l);//返回栈顶数据top int check_empty(b_stack &l);//检查是否为空empty }; void a_stack::push_num(a_stack &l,double i) { int k; l.length++; k=l.length; l.donser[k]=i; } void a_stack::pop_num(a_stack &l) { int k; k=l.length; l.length--; l.donser[k]=0; } double a_stack::top_num(a_stack &l) { return l.donser[l.length]; } int a_stack::check_empty(a_stack &l)//1为空 { if(l.length==0){return 1;} else return 0; } void b_stack::push_num(b_stack &l,char i) { int k; l.length1++; k=l.length1; l.donser1[k]=i; } void b_stack::pop_num(b_stack &l) { int k; k=l.length1; l.length1--; l.donser1[k]=0; } int b_stack::top_num(b_stack &l) { return l.donser1[l.length1]; } int b_stack::check_empty(b_stack &l)//1为空 { if(l.length1==0){return 1;} else return 0; } int i; double a,b; char s[250],c; int main() { cout<<"输入算式:\n"; while(gets(s),strcmp(s,"#")!=0) { b_stack s1; a_stack s2; for(i=0;s[i];i++) { if(s[i]>='0'&&s[i]<='9') //如果是数字继续找数字 { a=0; while(s[i]>='0'&&s[i]<='9') { a=a*10+s[i]-'0'; i++; } i--; s2.push_num(s2,a); } else if(s[i]=='(') //如果( { s1.push_num(s1,s[i]); } else if(s[i]==')') //如果) { while(s1.top_num(s1)!='(')//找不到前括号就循环 { c=s1.top_num(s1);//符号top s1.pop_num(s1);//删掉 a=s2.top_num(s2);//数字top s2.pop_num(s2);//删掉 b=s2.top_num(s2);//当前数字top s2.pop_num(s2);//删掉 if(c=='+') a+=b; if(c=='-') a=b-a; if(c=='*') a=b*a; if(c=='/') a=b/a; s2.push_num(s2,a); } s1.pop_num(s1);//删除前括号 if(s1.check_empty(s1)==1){continue;} if(s1.top_num(s1)=='*') //去掉括号以后栈还是乘 { s1.pop_num(s1);//删掉 a=s2.top_num(s2);//数字top s2.pop_num(s2);//删掉 b=s2.top_num(s2);//当前数字top s2.pop_num(s2);//删掉 a=b*a; s2.push_num(s2,a); } } else if(s[i]=='-'||s[i]=='+') //如果是+- { if(s1.check_empty(s1)==0&&s1.top_num(s1)!='(')//优先级低或者一样交换符号 { c=s1.top_num(s1);//字符栈顶 s1.pop_num(s1);//删掉 a=s2.top_num(s2);//数字栈顶1 s2.pop_num(s2);//删掉 b=s2.top_num(s2);//数字栈顶2 s2.pop_num(s2);//删掉 if(c=='+') a+=b; if(c=='-') a=b-a; if(c=='*') a=b*a; if(c=='/') a=b/a; s2.push_num(s2,a);//运算以后的入数字栈 s1.push_num(s1,s[i]);//字符入栈 } else if(s1.check_empty(s1)==1||s1.top_num(s1)=='(')//如果空或者前括号 { s1.push_num(s1,s[i]);//字符入栈 } } else if(s[i]=='/') //如果除 { b=0; c=s[i];//存一下符号 if(s1.check_empty(s1)==1||s1.top_num(s1)=='(') //空就入栈不运算 { s1.push_num(s1,c); continue; } i+=2;//找符号后面的数字 while(s[i]>='0'&&s[i]<='9') { b=b*10+s[i]-'0'; i++; } i--;//找到数字 a=s2.top_num(s2);//取出数字栈顶 s2.pop_num(s2);//删掉 if(s1.top_num(s1)=='*') //优先级一样交换符号 { a=a*b; s1.pop_num(s1);//删除原来的 s1.push_num(s1,c);//换成新的 } else a=a/b;//优先级高做除法 s2.push_num(s2,a);//新数字入栈 } else if(s[i]=='*') //如果乘 { b=0; c=s[i]; if(s1.check_empty(s1)==1||s1.top_num(s1)=='(') { s1.push_num(s1,c); continue; } i+=2; if(s[i]=='(') { s1.push_num(s1,c); i--; continue; } while(s[i]>='0'&&s[i]<='9') { b=b*10+s[i]-'0'; i++; } i--; a=s2.top_num(s2); s2.pop_num(s2); if(s1.top_num(s1)=='/') { a=a/b; s1.pop_num(s1); s1.push_num(s1,c); } else if(s1.top_num(s1)!='/') { a=a*b; } s2.push_num(s2,a); } } while(!s1.check_empty(s1))//如果符号栈非空就循环 { c=s1.top_num(s1);//符号top s1.pop_num(s1);//删掉 a=s2.top_num(s2);//数字top s2.pop_num(s2);//删掉 b=s2.top_num(s2);//当前数字top s2.pop_num(s2);//删掉 if(c=='+') a+=b; if(c=='-') a=b-a; if(c=='*') a=b*a; if(c=='/') a=b/a; s2.push_num(s2,a); } printf("%.2f\n",s2.top_num(s2)); } return 0; }
( 1 - 2 ) * 3 + 4 - 5 / 6 12 + 5 * ( 2 + 3 ) * 6 / 2 - 4 998 + ( 36 / 18 - 1 ) * 2 #
#include<cstdio> #include<string.h> #include<stdlib.h> #include<iostream> using namespace std; const int STOCK_SIZE = 1000;//定义栈的大小 class myStack { public: myStack(); //构造函数,构造空栈 bool push(int x); //进栈操作 bool pop(); //出栈操作 void clear(); //清空栈 bool isEmpty(); //判断是否栈空 bool isFull(); //判断是否栈满 int& gettop(){return elem[top];} ~myStack(); private: int elem[STOCK_SIZE]; int top;//指向栈顶 }; //构造函数 myStack::myStack():top(-1) {} //进栈操作,进栈成功返回true,否则返回false; bool myStack::push(int x) { if(top == STOCK_SIZE - 1) { return false; } elem[++top] = x; return true; } //出栈操作,由形参x将元素带出主调函数,出栈成功返回true,否则返回false; bool myStack::pop() { if(top == -1) { return false; } elem[top--]; return true; } //清空栈,使栈为空; void myStack::clear() { top = -1; } //判断栈是否为空 bool myStack::isEmpty() { return top == -1; } //判断栈是否栈满 bool myStack::isFull() { return top == STOCK_SIZE - 1; } //析构函数 myStack::~myStack(void) {} myStack s1; myStack s2; bool flag=false; char d[100][100]; int lebal[100][100]; int a,b,xa,xb,ya,yb,i,j,k,nx,ny; int dx[] = {0,1, 0,-1}; int dy[] = {1,0,-1, 0}; int dfs(int x,int y) { lebal[x][y]=1; if(x==xb&&y==yb){flag=true;return 1;} else { for(int i=0;i<4;i++) { if(x+dx[i]<1||x+dx[i]>a||y+dy[i]<1||y+dy[i]>b){continue;} if(d[x+dx[i]][y+dy[i]]=='#') {continue;} if(lebal[x+dx[i]][y+dy[i]]==1) {continue;} if(flag) break; nx=x+dx[i]; ny=y+dy[i]; s1.push(nx); s1.push(ny); lebal[nx][ny]=1; dfs(nx,ny); lebal[nx][ny]=0; } } if(!flag) { s1.pop(); s1.pop(); } return 0; } int main() { cout<<"输入几乘几的矩阵?"<<endl; scanf("%d %d",&a,&b); cout<<"输入入口坐标"<<endl; scanf("%d %d",&xa,&ya); cout<<"输入出口坐标"<<endl; scanf("%d %d",&xb,&yb); cout<<"输入这个矩阵 #表示不可走,*可走\n"; for(i=1;i<=a;i++) { scanf("%s",&d[i][1]); } dfs(xa,ya); if(flag){cout<<"----找到,";} else cout<<"未找到,"; cout<<"路径:\n"; while(1) { s2.push(s1.gettop()); s1.pop(); s2.push(s1.gettop()); s1.pop(); if(s1.isEmpty()){break;} } while(s2.isEmpty()!=1) { cout<<"x:"<<s2.gettop()<<" "; s2.pop(); cout<<"y:"<<s2.gettop()<<" "; s2.pop(); cout<<endl; } return 0; }
10 10 1 2 10 9 #*######*# ******#**# *#*##*##*# *#******** ##*##*#### ****#****# *#######*# ****#***** *####*###* ****#****# 6 8 2 2 5 7 ######## #**#***# ##*****# #**#*#*# #******# ########
实验五
编写链式queue类,实现输出指定层数的杨辉三角
#include<iostream> #include<cstdio> #define news 900 #define http 2333 using namespace std; template<typename Dong> class queues { private: int head; int tail; int sum;//长度 int num;//容量 Dong* data; public: queues(); ~queues(); bool empty(); bool full(); Dong top(); Dong bottom(); void inqueues(Dong const& l); Dong outqueues(); }; template <typename Dong> queues<Dong>::queues() { head=tail=sum=0; num=news; data=new Dong[news]; } template <typename Dong> queues<Dong>::~queues() { delete []data; } template <typename Dong> bool queues<Dong>::empty() { return !sum; } template <typename Dong> bool queues<Dong>::full() { return sum<num? false:true; } template <typename Dong> Dong queues<Dong>::top() { return data[head]; } template <typename Dong> Dong queues<Dong>::bottom() { return data[tail]; } template <typename Dong> void queues<Dong>::inqueues(Dong const& l) { if(full()) return; data[tail]=l; tail++; sum++; } template <typename Dong> Dong queues<Dong>::outqueues() { Dong temp=0; temp=data[head]; sum--; head=head+1; return temp; } int main() { int i,k,a,b=0,c,d,e=0; queues<int> donser; cout<<"输入层数:\n"; scanf("%d",&a); k=a;c=1; while(1) { b++; for(i=1;i<=k;i++){cout<<" ";} k--; if(b==1){cout<<" 1"<<endl;continue;} if(b==2) { cout<<" 1 1"<<endl; donser.inqueues(1); donser.inqueues(2); donser.inqueues(1); continue; } donser.inqueues(1); donser.inqueues(1); c=d=http; while(1) { if(c==http) { c=donser.outqueues(); if(c<10){cout<<" "<<c;} else cout<<" "<<c; } else c=e; d=donser.outqueues(); if(c==1&&d==1){break;} if(d<10){cout<<" "<<d;} else cout<<" "<<d; c+=d; donser.inqueues(c); e=d; } cout<<endl; donser.inqueues(1); if(b>=a){break;} } return 0; }
实验六
编写链式二叉树
(1)用递归读取数据
(2)先序中序后序遍历二叉树
(3)求所有节点数量
(4)求二叉树深度
(5)其他
#include<iostream> #include<cstdio> using namespace std; struct tree { int data; tree *lson,*rson; }; class DonserTree { static int n; static int m; public: tree *root; DonserTree() {root=NULL;}//root初始化 void create_DonserTree(int);//建树 void Preorder(tree *);//先序遍历 void inorder(tree *);//中序遍历 void Postorder(tree *);//后序遍历 void Prcout() {Preorder(root); cout<<endl;} void Incout() {inorder(root); cout<<endl;} void Pocout() {Postorder(root); cout<<endl;} int count(tree *);//计二叉树的节点个数 void deepth(tree *);//计层数 int findleaf(tree *);//求二叉树叶子的个数 int findnode(tree *);//求二叉树中度数为1的结点数量 void deleted(tree *&root);//删除节点 ~DonserTree();//析构函数 }; DonserTree A; int maxDeep=0,deep=1; int DonserTree::n=0; int DonserTree::m=0; void DonserTree::create_DonserTree(int x) { tree *node=new tree; node->data=x; node->rson=node->lson=NULL; if(root==NULL) root=node; else { tree *back; tree *current=root; while(current!=NULL) { back=current; if(current->data>x) current=current->lson; else current=current->rson; } if(back->data>x) back->lson=node; else back->rson=node; } } int DonserTree::count(tree *p)//递归计数 { if(p==NULL) return 0; else return count(p->lson)+count(p->rson)+1; } void DonserTree::Preorder(tree *temp)//先序遍历输出二叉树 { if(temp!=NULL) { cout<<temp->data<<" "; Preorder(temp->lson); Preorder(temp->rson); } } void DonserTree::inorder(tree *temp)//中序遍历输出二叉树 { if(temp!=NULL) { inorder(temp->lson); cout<<temp->data<<" "; inorder(temp->rson); } } void DonserTree::Postorder(tree *temp)//后序遍历输出二叉树 { if(temp!=NULL) { Postorder(temp->lson); Postorder(temp->rson); cout<<temp->data<<" "; } } void DonserTree::deepth(tree *temp) { if(temp->rson==NULL&&temp->lson==NULL) return; if(temp->lson!=NULL) { deep++; if(deep>=maxDeep) maxDeep=deep; deepth(temp->lson); deep--; } if(temp->rson!=NULL) { deep++; if(deep>=maxDeep) maxDeep=deep; deepth(temp->rson); deep--; } } int DonserTree::findleaf(tree *temp) { if(temp==NULL) return 0; else { if(temp->lson==NULL&&temp->rson==NULL) return n++; else { findleaf(temp->lson); findleaf(temp->rson); } return n; } } int DonserTree::findnode(tree *temp) { if(temp==NULL) return 0; else { if(temp->lson!=NULL&&temp->rson!=NULL) { findnode(temp->lson); findnode(temp->rson); } if(temp->lson!=NULL&&temp->rson==NULL) { m+=1; findnode(temp->lson); } if(temp->lson==NULL&&temp->rson!=NULL) { m+=1; findnode(temp->rson); } } return m; } void DonserTree::deleted(tree *&root) { if((root->lson==0)&&(root->rson==0)){delete root;} if(root->lson!=0){deleted(root->lson);root->lson=NULL;} if(root->rson!=0){deleted(root->rson);root->rson=NULL;} } DonserTree::~DonserTree() {} int main() { int array[1000],a; cout<<"输入有几个节点\n"; scanf("%d",&a); cout<<"按先序输入作为结点的数字\n"; for(int i=1;i<=a;i++) {scanf("%d",&array[i-1]);} cout<<"建立排序二叉树顺序: "<<endl; for(int i=0;i<a;i++) { cout<<array[i]<<" "; A.create_DonserTree(array[i]); } cout<<endl; cout<<"二叉树节点个数: "<<A.count(A.root)<<endl; cout<<"二叉树叶子个数:"<<A.findleaf(A.root)<<endl; A.deepth(A.root);cout<<"二叉树层数:"<<maxDeep<<endl; cout<<"二叉树中度数为1的结点的数量为:"<<A.findnode(A.root)<<endl; cout<<"先序遍历序列: ";A.Prcout(); cout<<"中序遍历序列: ";A.Incout(); cout<<"后序遍历序列: ";A.Pocout(); return 0; }
实验七
一些基本算法
(1)实现二分法查找
(2)建立二叉排序算法并将二叉排序树分层输出
(3)输入数据建立平衡二叉树,计算排序数与二叉平衡树的度
(4)自行编写排序算法
#include <cstdio> #include <cstdlib> #include <iostream> using namespace std; int d[1000],mid,n,i,b; int q_sort(const void*a,const void*b) { return *(int*)a-*(int*)b; } void erfen(int num,int x,int y) { mid=(x+y)>>1; if(d[mid]==d[num]){i=1;return;} else if(mid<0||mid+1==n-1){return;} else { erfen(num,0,mid); erfen(num,mid,n); } return; } int main() { cout<<"输入数据的个数:"<<endl; scanf("%d",&n); cout<<"输入这些数据:"; for(i=0;i<n;i++) {scanf("%d",&d[i]);} cout<<"输入要找的数据,下面是二分查找:"<<endl; scanf("%d",&b); qsort(d,n,sizeof(int),q_sort); erfen(b,0,n-1); if(i==1) cout<<"Yes\n"; else cout<<"No\n"; return 0; }
1-2 实验六不小心写成了二叉排序树,不贴代码了
/************************************************************************/ /* 别人写的平衡二叉树---AVL */ /************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <iostream> using namespace std; #define LH +1 #define EH 0 #define RH -1 typedef int ElemType; typedef struct BSTNode { ElemType data; int bf;//balance flag struct BSTNode *lchild,*rchild; }*PBSTree; void R_Rotate(PBSTree* p) { PBSTree lc = (*p)->lchild; (*p)->lchild = lc->rchild; lc->rchild = *p; *p = lc; } void L_Rotate(PBSTree* p) { PBSTree rc = (*p)->rchild; (*p)->rchild = rc->lchild; rc->lchild = *p; *p = rc; } void LeftBalance(PBSTree* T) { PBSTree lc,rd; lc = (*T)->lchild; switch (lc->bf) { case LH: (*T)->bf = lc->bf = EH; R_Rotate(T); break; case RH: rd = lc->rchild; switch(rd->bf) { case LH: (*T)->bf = RH; lc->bf = EH; break; case EH: (*T)->bf = lc->bf = EH; break; case RH: (*T)->bf = EH; lc->bf = LH; break; } rd->bf = EH; L_Rotate(&(*T)->lchild); R_Rotate(T); break; } } void RightBalance(PBSTree* T) { PBSTree lc,rd; lc= (*T)->rchild; switch (lc->bf) { case RH: (*T)->bf = lc->bf = EH; L_Rotate(T); break; case LH: rd = lc->lchild; switch(rd->bf) { case LH: (*T)->bf = EH; lc->bf = RH; break; case EH: (*T)->bf = lc->bf = EH; break; case RH: (*T)->bf = EH; lc->bf = LH; break; } rd->bf = EH; R_Rotate(&(*T)->rchild); L_Rotate(T); break; } } int InsertAVL(PBSTree* T,ElemType e,bool* taller) { if ((*T)==NULL) { (*T)=(PBSTree)malloc(sizeof(BSTNode)); (*T)->bf = EH; (*T)->data = e; (*T)->lchild = NULL; (*T)->rchild = NULL; } else if (e == (*T)->data) { *taller = false; return 0; } else if (e < (*T)->data) { if(!InsertAVL(&(*T)->lchild,e,taller)) return 0; if(*taller) { switch ((*T)->bf) { case LH: LeftBalance(T); *taller = false; break; case EH: (*T)->bf = LH; *taller = true; break; case RH: (*T)->bf = EH; *taller = false; break; } } } else { if(!InsertAVL(&(*T)->rchild,e,taller)) return 0; if (*taller) { switch ((*T)->bf) { case LH: (*T)->bf = EH; *taller = false; break; case EH: (*T)->bf = RH; *taller = true; break; case RH: RightBalance(T); *taller = false; break; } } } return 1; } bool FindNode(PBSTree root,ElemType e,PBSTree* pos) { PBSTree pt = root; (*pos) = NULL; while(pt) { if (pt->data == e) { //找到节点,pos指向该节点并返回true (*pos) = pt; return true; } else if (pt->data>e) { pt = pt->lchild; } else pt = pt->rchild; } return false; } void InorderTra(PBSTree root) { if(root->lchild) InorderTra(root->lchild); printf("%d ",root->data); if(root->rchild) InorderTra(root->rchild); } int main() { int i,nArr[1000],n; PBSTree root=NULL,pos; bool taller; cout<<"输入数据的个数:"<<endl; scanf("%d",&n); cout<<"输入这些数据:"; for(i=0;i<n;i++) {scanf("%d",&nArr[i]);} for (i=0;i<n;i++) {InsertAVL(&root,nArr[i],&taller);} InorderTra(root); cout<<endl; cout<<"输入要找的数据,下面是平衡树查找:"<<endl; scanf("%d",&n); if(FindNode(root,n,&pos)) printf("\nYes:%d\n",pos->data); else printf("\nNo!\n"); return 0; }
作业一
编写链式list类实现集合的交并补
#ifndef List_H_ #define List_H_ #include <stdio.h> #include <malloc.h> #include <string.h> #include <stdlib.h> #include <iostream> #define InsertNUM 10 using namespace std; typedef struct { int *Ptr; int Length; int DongSize; }DonserList; void Delete(DonserList &A,int i); int HavePtr(DonserList L,int num); int FindPtr(DonserList L,int num); void Bing(DonserList A,DonserList B,DonserList &C); void Jiao(DonserList A,DonserList B,DonserList &D); void Cha(DonserList &A,DonserList D); void Malloc(int al,int bl,DonserList &A,DonserList &B,DonserList &C,DonserList &D); void Judge (int al,int bl,DonserList &A,DonserList &B,DonserList &C,DonserList &D); void Sscanf(int il,int al,int bl,DonserList &A,DonserList &B,DonserList &C,DonserList &D); #endif // List_H_
#include"head.h" void Malloc(int al,int bl,DonserList &A,DonserList &B,DonserList &C,DonserList &D) { A.Ptr = (int *)malloc(al*sizeof(int)); B.Ptr = (int *)malloc(bl*sizeof(int)); C.Ptr = (int *)malloc((al>bl?al:bl)*sizeof(int)); D.Ptr = (int *)malloc((al<bl?al:bl)*sizeof(int)); } void Judge(int al,int bl,DonserList &A,DonserList &B,DonserList &C,DonserList &D) { if(!A.Ptr||!B.Ptr||!C.Ptr||!D.Ptr) { printf("WrongPUT!~"); exit(0); } else { A.Length=0; A.DongSize=al; B.Length=0; B.DongSize=bl; C.Length=0; C.DongSize=(al>bl)?al:bl; D.Length=0; D.DongSize=(al<bl)?al:bl; } } void Sscanf(int il,int al,int bl,DonserList &A,DonserList &B,DonserList &C,DonserList &D) { printf("输入集合A的元素:"); for(il=0;il<al;il++) { scanf("%d",(A.Ptr+il)); A.Length++; } printf("输入集合B的元素:"); for(il=0;il<bl;il++) { scanf("%d",(B.Ptr+il)); B.Length++; } } void Delete(DonserList &A,int i) //删除用 { int *p,*q; if(i<0||i>A.Length) { printf("WrongPUT!"); exit(0); } p =A.Ptr+i-1; q =A.Ptr+A.Length-1; for(++p;p<= q;++p) *(p-1)=*p; --A.Length; } int HavePtr(DonserList L,int num) //获取指针 { if(num<0||num>L.Length) printf("WrongPUT!"); return *(L.Ptr+num); } int FindPtr(DonserList L,int num) //查找位置 { int i; for(i=0;i<L.Length;i++) { if(num==*(L.Ptr+i)) return i+1; } return 0; } void Bing(DonserList A,DonserList B,DonserList &C)//A并B { int i,j,k,e,*newbase; for(i=0;i<A.Length;i++) { C.Ptr[i]=A.Ptr[i]; C.Length++; } for(j=0;j<B.Length;j++) { e=HavePtr(B,j); k=FindPtr(C,e); if(k==0) { if((C.Length)>=C.DongSize)//扩容 { newbase=(int *)realloc(C.Ptr,(C.DongSize+InsertNUM)*sizeof(int)); if(!newbase) exit(0); C.Ptr=newbase; C.DongSize+=InsertNUM; } C.Ptr[C.Length]=B.Ptr[j]; C.Length++; } } printf("A B的并集C = {"); for(k = 0; k < C.Length; k++) printf("%d ",*(C.Ptr+k)); printf("}\n"); } void Jiao(DonserList A,DonserList B,DonserList &D)//A交B { int i,k,t,*p; p=D.Ptr; for(i=0;i<A.Length;i++) { t=HavePtr(A,i); k=FindPtr(B,t); if(k>0) { *p++=t; D.Length++; } } if(D.Length==0) printf("A B的交集为空集\n"); else { printf("A B的交集为C = {"); for(i = 0; i < D.Length; i++) printf("%d ",*(D.Ptr+i)); printf("}\n"); } } void Cha(DonserList &A,DonserList D)//A与B差集 { int i,num,ls; for(i=0;i< D.Length;i++) { ls=HavePtr(D,i); num=FindPtr(A,ls); Delete(A,num); } if(A.Length == 0) printf("A B的差集为空\n"); else { printf("A B的差集E = {"); for(i=0;i<A.Length;i++) printf("%d ",*(A.Ptr+i)); printf("}\n"); } }
#include"head.h" int main() { DonserList A,B,C,D; int i,a,b; printf("输入集合A元素a= "); scanf("%d",&a); printf("输入集合B元素b= "); scanf("%d",&b); Malloc(a,b,A,B,C,D); Judge(a,b,A,B,C,D); Sscanf(i,a,b,A,B,C,D); Bing(A,B,C); Jiao(A,B,D); Cha(A,D); system("pause"); return 0; }
作业二
编写C++单链表类,实现其相应功能,顺序表的就地转置,注意是就地转置。
#include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; struct donser { int data; donser* next; }; class list { donser* head; donser* head2; donser* tmp; donser* tmp2; public: list(){head=NULL;} //头结点单链表的初始化 void listinsert(int i);//尾插法完成链表生成 void coutlist();//查看当前链表 void coutlist2();//查看当前链表 int seelength();//求单链表表长 void chain_exchange();//链表就地逆置 ~list();//在析构函数中完成链表内存释放 }; //#include"head.h" void list::listinsert(int i) { int x,j; j=i; donser*u; donser*r; donser*l; l=new donser; r=l; scanf("%d",&x); while(1) { j--; u=new donser; u->data=x; if(j==i-1){head=u;} u->next=NULL; r->next=u; r=u; if(j==0){break;} scanf("%d",&x); } } void list::coutlist() { donser *a; a=head; cout<<" 当前序列:"; while(a->next!=NULL) { cout<<a->data<<" "; a=a->next; } cout<<a->data<<" "; cout<<endl; } void list::coutlist2() { donser *a; a=head2; cout<<" 当前序列:"; a=a->next; while(a->next!=NULL) { cout<<a->data<<" "; a=a->next; } cout<<a->data<<" "; cout<<head2->data; cout<<endl; } int list::seelength() { donser *a; int i=1; a=head; while(a->next!=NULL) { a=a->next; i++; } return i; } void list::chain_exchange() { int k,i,m,n; donser *a,*b; head2=head; a=head2; k=seelength(); m=k;m--; for(i=1;;i++) { tmp=a->next; a->next=a->next->next; b=a->next; m--;n=m; while(n>=2) { b=b->next;n--; } tmp2=b->next; b->next=tmp; b->next->next=tmp2; if(i==k){k=k-2;break;} } while(k>=1) { b=b->next;k--; } b->next=NULL; head2=a; coutlist2(); } list::~list() { donser *a; while(head!=NULL) { a=head; head=a->next; delete a; } } //#include"head.h" int main() { int m; list a; cout<<"*输入数据,利用尾插法完成链表生成\n"; cout<<" 输入要插入几个数据\n"; scanf("%d",&m); a.listinsert(m); cout<<"*查看已经存入的结点数据\n"; a.coutlist(); cout<<"*就地置换\n"; a.chain_exchange(); //a.coutlist2(); a.~list(); cout<<" 已释放内存\n"; system("pause"); return 0; }
#include <iostream> using namespace std; struct node { int data; node * Next; }; int main() { cout<<"请输入表长"<<endl; int n; node *head=new node; head->data=0; head->Next=NULL; cin>>n; node * temp=head; cout<<"请输入表:"<<endl; for(int i=0; i<n; ++i) { node * a = new node; cin>>a->data; a->Next=NULL; temp->Next=a; temp=a; } temp=head->Next; cout<<"原表是: "; for(int i=0; i<n; ++i) { cout<<temp->data<<" "; temp=temp->Next; } temp = head->Next; for(int i=1; i<n; ++i) { //进行n-1次循环就行了 node * a = head->Next; node * temp1 = temp->Next; temp->Next=temp1->Next; head->Next=temp1; head->Next->Next=a; } temp=head->Next; cout<<"\n翻转串是: "; for(int i=0; i<n; ++i) { cout<<temp->data<<" "; temp=temp->Next; } cout<<endl; return 0; }
作业三
(1)栈操作,a判断一个序列是否可以由另一个序列通过栈操作得到,b输出所有栈操作得到的结果
(2)背包问题(多重部分和)
(3)斐波那契数列的递归实现和循环实现
#include<iostream> #include<cstring> #include<stdlib.h> #include<stdio.h> #include<stack> using namespace std; int a[100]; int b[100]; stack<int>s; int Catalan_number(int i)//i为位数 { int j=1,lebal=1,k=1; while(1) { if(k==i+1){break;} if(a[j]==b[k]){k++;if(j<i)j++;} else { if(j>=i&&s.top()!=b[k]){lebal=0;break;} if(s.empty()==1){s.push(a[j]);j++;continue;} if(s.top()==b[k]){s.pop();k++;continue;} if(s.top()!=b[k]&&j<i){s.push(a[j]);j++;continue;} if(j==i&&s.top()==b[k]){s.pop();k++;} } } while(!s.empty()) {s.pop();} return lebal; } int main() { int d,i; cout<<"输入位数:\n"; scanf("%d",&d); cout<<"你的输入序列是序列:\n"; for(i=1;i<=d;i++) {scanf("%d",&a[i]);} cout<<"输入要查找的序列:\n"; for(i=1;i<=d;i++) {scanf("%d",&b[i]);} if(!Catalan_number(d)){cout<<"不存在\n";} else cout<<"存在\n"; cout<<endl; return 0; }
#include<iostream> #include<stdlib.h> #include<cstring> #include<stdio.h> #include<stdio.h> #include<string> #include<stack> using namespace std; char string1[]="123456789a"; int length,dd,loop=1; int used[10]= {0}; char output[10]; int donser[10]; stack<int>s; int a[100]; int b[100]; int Catalan_number(int i)//卡特兰数 i为位数 { int j=1,lebal=1,k=1; while(1) { if(k==i+1){break;} if(a[j]==b[k]){k++;if(j<i)j++;} else { if(j>=i&&s.top()!=b[k]){lebal=0;break;} if(s.empty()==1){s.push(a[j]);j++;continue;} if(s.top()==b[k]){s.pop();k++;continue;} if(s.top()!=b[k]&&j<i){s.push(a[j]);j++;continue;} if(j==i&&s.top()==b[k]){s.pop();k++;} } } while(!s.empty()) {s.pop();} return lebal; } void Fun(int d) //处理全排列 { int i; for(i=0;i<=length;i++) { if(!used[i]) { used[i]=1; output[d]=string1[i]; if(d==length) { for(d=0;d<length;d++) { if(output[d]=='a')printf("10 "); else { donser[d]=output[d]; b[loop]=donser[d]-48; loop++; } } if(output[length]=='a')printf("10\n"); else { donser[length]=output[length]; b[loop]=donser[length]-48; if(!Catalan_number(dd)){goto nn;} else cout<<"正确序列:"; for(int yy=1;yy<=dd;yy++) cout<<b[yy]<<" "; cout<<endl; nn: loop=1; } } else Fun(d+1); used[i]=0; } } } int main() { int i; cout<<"输入位数:\n"; scanf("%d",&dd); cout<<"你的输入序列是:\n"; for(i=1;i<=dd;i++) {scanf("%d",&a[i]);} cout<<"输出所有正确序列:\n"; string1[dd]=0; length=strlen(string1)-1; Fun(0); return 0; }
#include<iostream> #include<cstring> #include<stdlib.h> #include<stdio.h> using namespace std; int dp[100]; int n,i; int kl; int a[100]; int d[100]; int m[100]; int quicksort(const void*a,const void*b) { return *(int*)a-*(int*)b; } void solve() { memset(dp,-1,sizeof(dp)); dp[0]=0; for(int i=0;i<n;i++) { for(int j=0;j<=kl;j++) { if(dp[j]>=0) { dp[j]=m[i]; } else if(j<a[i]||dp[j-a[i]]<=0) { dp[j]=-1; } else{ dp[j]=dp[j-a[i]]-1; } } } if(dp[kl]>=0){printf("Yes\n");} else printf("No\n"); } int main() { int y=-1,t=0,tt=0; cout<<"输入有几个物品:"; scanf("%d",&n); cout<<"输入物品重量:\n"; for(i=0;i<n;i++) {scanf("%d",&d[i]);} qsort(d,n,sizeof(int),quicksort); for(i=0;i<n;i++) { y++; if(d[i]!=d[i+1]){m[y]=1;a[y]=d[i];} else if(d[i]==d[i+1]) { t=i+1; a[y]=d[i]; while(d[i]==d[t]) { t++; tt++; } t--;tt++; i=t; m[y]=tt; tt=t=0; } } cout<<"总重量是多少:\n"; scanf("%d",&kl); solve(); return 0; }
#include<string> #include<iostream> #include<iosfwd> #include<cmath> #include<cstring> #include<stdlib.h> #include<stdio.h> #include<cstring> using namespace std; long long f[1000]; int main() { int i; long long a; cout<<"cin a fionacci:\n"; f[4]=3;f[1]=1;f[2]=1;f[3]=2; for(i=5;i<=1000;i++) { f[i]=f[i-1]+f[i-2]; } while(cin>>a) { cout<<f[a]<<endl; } return 0; }
#include<string> #include<iostream> #include<cmath> #include<cstring> #include<stdio.h> using namespace std; int fm[10]; int f(int i) { if(i==0){return 0;} if(i==1){return 1;} return f(i-1)+f(i-2); } int main() { int a; fm[4]=3;fm[1]=1;fm[2]=1;fm[3]=2; while(cin>>a) { if(a>=1&&a<=4){cout<<fm[a]<<endl;} else cout<<f(a)<<endl; } return 0; }