复习

来源:互联网 发布:mac自带视频剪辑 编辑:程序博客网 时间:2024/04/29 07:38

合并:

这个比较简单,就大概的说下,先把两个序列合并,然后对序列进行len-1次相互元素的比较,即冒泡,最后得出一个有序序列
我觉得这种思想挺重要的,很多问题你可以用分治法去解决,但是中间过程步骤你可能先整体考虑,然后进行局部处理。

Node *Sort_Elem(Node *head){Node p;              //p变量主要是在冒泡里面做临时变量Node *q;int i=1,len;len=List_length(head);//cout<<len<<" ";q=new Node;q=head;//Out_list(p);p.data=0;p.next=NULL;cout<<head->next->data<<endl;while(true)                  //这里我用了冒泡排序,其他排序你们可以自己尝试下{                            while(head->next!=NULL)  //这里要从head->next开始判断,和普通的冒泡排序类似{if((head->data) > (head->next->data)){p.data=head->next->data;head->next->data=head->data;head->data=p.data;}head=head->next;}i++;if(i==len)  return q;  //循环跳出条件head=q;                //q主要是在一次冒泡过后,将头指针复位}}void Combine_list(Node *head1,Node *head2){Node *p;p=new Node;p=head1;          //先将头指针赋给pwhile(head1=head1->next)   if(head1->next==NULL)   {   head1->next=head2;   p=Sort_Elem(p);   Out_list(p);   return;   }}


栈:(记住头尾指针和栈长度)
栈这个东西,其实会用就行,毕竟STL里面有类模板,个人认为代码越简单越好,因为有些特殊的情况不是每个人都能考虑到的
用的多了,自然就会,所以把大致的思想理清楚就可以了。
下面是精简了很多的代码,基本上是主要内容都有了。

 

void Init_stack(Stack &S){S.base = new int[Max];S.top = S.base;S.length = Max;}void Push(Stack &S,int e)  {if(S.top - S.base == S.length){printf("栈已满!\n");return;}*S.top = e;S.top++;}void Pop(Stack &S,int &e)   //STL里面的stack出栈只是Pop(); 后面一个参数作用不大{if(S.top == S.base)printf("栈已空\n");S.top--;e = *S.top;}int Gettop(Stack &S){if(S.top == S.base)printf("栈已空!\n");return (*(S.top-1));}int Stack_length(Stack &S){Stack flag;flag.top = S.top;int k=0;while(flag.top--){k++;if(flag.top == S.base)return k;}}void Out_stack(Stack &S){Stack flag;flag.top = S.top;while(flag.top--){printf("%d ",*flag.top);if(flag.top == S.base){printf("\n");return;}}}


 

进制转换的函数:
这个希望都能记住,因为这种取模求余的思想在很多题目上都会有体现,像大数问题,某些字符串问题和欧几里德类的问题。

void change(Stack S,int a,int b){int s=0,c,k;k=a;while(a){Push(S,a%b);a/=b;}while(S.base != S.top){s += Gettop(S);s *= 10;Pop(S,c);}cout<<"十进制数 "<<k<<" 转换为 "<<b<<" 进制数为: "<<s/10<<endl;}


括号匹配源代码:
括号匹配只是栈里面的一个简单的运用,帮助你理解栈的实质思想吧,自我感觉没什么技巧可言

 

void Kuo_hao(Stack &S){char c[101];int flag = 1,i,e;cin>>c;          //读入数据for(i=0;c[i]!='\0';i++){if(c[i] == '(' || c[i] == '[')Push(S,(int)c[i]);       //压栈if(c[i] == ')')              //如果匹配,弹出,标记,break用不用无所谓{if( (char)Gettop(S) == '(' )Pop(S,e);elseflag = 0;}if(c[i] == ']'){if( (char)Gettop(S) == '[' )Pop(S,e);elseflag = 0;}}if(S.top == S.base && flag)cout<<"所输入的括号匹配成功!"<<endl;elsecout<<"所输入的括号匹配失败!"<<endl;}


 

//这里的链式队列步骤基本是按照书本上的,可以自己尝试不加头结点,如何构造链式队列,并且基本操作可以执行

这里的链式队列操作无非就是创建,销毁,增加(减少),查找,更新这些操作
所以你基本记住一个头指针和一个尾指针,剩下的就是移动这些指针来操作,中间步骤无非就是临时创建一个指针或者一个存储单位
有些时候,你要先想下如果插入是否会溢出,主函数传递过来的能不能在调用的函数里面进行操作,头指针和尾指针什么时候相遇。。。
大概就是这些内容

void Init_queue(LinkQueue &Q){ Q.front=Q.rear=new QNode;Q.front->next=NULL; // 头结点的next域为空}void Destroy_queue(LinkQueue &Q){ while(Q.front) // Q.front不为空{ Q.rear=Q.front->next; // Q.rear指向Q.front的下一个结点delete Q.front; // 释放Q.front所指结点Q.front=Q.rear; // Q.front指向Q.front的下一个结点}}bool Queue_empty(LinkQueue Q){ if(Q.front->next==NULL)return true;elsereturn false;//return !(Q.front->next);  精简}int Queue_length(LinkQueue Q){ int i=0; QueuePtr p=Q.front; // 临时指针p指向头结点while(Q.rear!=p){ i++; p=p->next; // p指向下一个结点}return i;}int Get_head(LinkQueue Q,QElemType &e){ QueuePtr p;if(Q.front==Q.rear) return 0;p=Q.front->next; e=p->data;return 1;}void En_queue(LinkQueue &Q,QElemType e){QueuePtr p;p=new QNode; // 动态生成新结点if(!p)exit(1); p->data=e;p->next=NULL; Q.rear->next=p; // 原队尾结点的指针指向新结点Q.rear=p; // 尾指针指向新结点}int De_queue(LinkQueue &Q,QElemType &e){ QueuePtr p;if(Q.front==Q.rear) return 0;p=Q.front->next; // p指向队头结点e=p->data; Q.front->next=p->next; // 头结点指向下一个结点if(Q.rear==p) // 删除的是队尾结点Q.rear=Q.front; // 修改队尾指针指向头结点(空队列)delete p; return 1;}void Queue_traverse(LinkQueue Q,void(*visit)(QElemType)) //从队头到队尾依次对队列Q中每个元素调用函数visit(){ QueuePtr p;p=Q.front->next; // p指向队头结点while(p) // p指向结点{ visit(p->data); // 对p所指元素调用visit()p=p->next; // p指向下一个结点}printf("\n");}


 

下面的是二叉树的构建,遍历,计数,复制的基本操作
二叉树,首先你要想到,它要有左右孩子,所以这个时候,你要选择递归的方式来解决问题
上面的这些操作都用到了递归,构建无非就是开辟一个节点,然后左右递归,遍历类似
计数和复制  你要先判断树有没有构建,然后进行操作
关于递归的技巧  多敲敲就会了

 

BiTNode *CreateBiTree(){    char ch;    BiTNode *T;    scanf("%c",&ch);    if(ch=='#')T=NULL;    else{        T = new BiTNode;        T->data = ch;        T->lchild = CreateBiTree();        T->rchild = CreateBiTree();    }    return T;//返回根节点}int Depth(BiTNode *T){if(T == NULL) return 0;elsereturn Depth(T->lchild)>Depth(T->rchild)?Depth(T->lchild)+1:Depth(T->rchild)+1;}int NodeCount(BiTNode *T,int &Yezi,int &flag){if(T == NULL)return 0;else{if(T->lchild == NULL && T->rchild == NULL) Yezi++;if(T->lchild != NULL && T->rchild != NULL) flag++;return NodeCount(T->lchild,Yezi,flag) + NodeCount(T->rchild,Yezi,flag) + 1;}}//先序遍历二叉树void PreOrderTraverse(BiTNode *T){    if(T){printf("%c",T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);    }}//中序遍历void InOrderTraverse(BiTNode *T){    if(T){PreOrderTraverse(T->lchild);printf("%c",T->data);PreOrderTraverse(T->rchild);    }}//后序遍历void PostOrderTraverse(BiTNode *T){    if(T){PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);printf("%c",T->data);    }}void Copy(BiTNode *T,BiTNode *(&TT))//  囧(/ □ \),这个地方指针问题调试了好久,各种情况都试了一下,最后终于OK了!{if(T == NULL){TT = NULL;return;}else{TT = new BiTNode;TT->data = T->data;Copy(T->lchild,TT->lchild);Copy(T->rchild,TT->rchild);}}


顺序查找 没什么说的,遍历就行
二分查找里面,你要知道的就是一个low,一个high下标
因为你每次都是二分,直到不能再分为止,所以一个while循环,里面就是结束的临界点
然后while循环里面你要操作,这个时候你就判断如果找到了,直接跳出。

int Search_Seq(SSTable ST,int x,int &k){int i;for(i = 1; i <= ST.length; i++,k++){if(ST.R[i].key == x)return i;}return -1;}int Search_Bin(SSTable ST,int x,int &k){int i;int low,high;low = 1; high = ST.length;while(low<=high){k++;int mid = (low+high)/2;if(ST.R[mid].key == x)return mid;else if(ST.R[mid].key < x)low = mid + 1;elsehigh = mid - 1;}return -1;}


 

下面的就是图了
图里面有很多算法,dfs和bfs是比较简单基础的
那么怎么来记呢
dfs就是创建好了一个邻接矩阵后,对里面的元素先for循环遍历,对于每遍历一个元素
此时你要标记它访问过,然后再访问和这个元素有关的其他元素,并且其他元素也是没有标记的
这里就有点像栈的形式,不断向下搜索
void DFS(AMGraph &G,int k){    int j;    visited[k]=true;    cout<<G.vexs[k]<<" ";    for(j=0;j<G.vexnum;j++)    {        if(!visited[j]&&G.arcs[k][j]!=MaxInt)            DFS(G,j);    }}


而对于bfs来说,就类似于先找出一个点,然后把与这个点有关的所有点都遍历完
全部存放到队列里面,所以while循环里面你要先从队列里面弹出一个元素,进行操作,这个操作就会把所有有关的点全部压入队列
所以不断重复操作,直到队列非空
大概思路就是这样的
和bfd有关的题目主要是迷宫之类的

 

void BFS(ALGraph &G,char v){cout<<v<<" ";  visited[v]=true;char flag,k;queue<char>q;q.push(v);while(!q.empty()){flag=q.front();//cout<<flag;q.pop();ArcNode *pp;pp = new ArcNode;pp=G.vertices[LocateVex(G,flag)].firstarc;//cout<<pp->adjvex<<endl;//k=G.vertices[pp->adjvex];for(;pp!=NULL;pp=pp->nextarc){k=G.vertices[pp->adjvex].data;//cout<<visited[k];if(!visited[k]){cout<<k<<" ";//cout<<q.empty();visited[k]=true;q.push(k);}}}//cout<<"nihao";}


二叉排序树:
主要是构建,查找,插入,删除操作
构建这里就是不断调用插入函数来实现,while循环建议用9999999这种大数形式
因为书上给的伪代码在数据类型上不同,所以导致用#这种会错
然后是插入函数里面无非就是递归插入(因为二叉树嘛!),在查找函数上,也主要是递归形式吧
删除函数上面,因为要删的是参数的节点,所以你首先要查找到这个节点,定位好后,你要根据中序遍历的结果
删除相应的节点,并且保证操作后的中序序列仍能保持原来的序(貌似老师上课是这样说的),不过我觉的你按照代码的步骤
在纸上画画,大概也就是删节点,孩子节点替代。。

BSTree SearchBST(BSTree T,int key){if(!T || key == T-> data.key){//cout<<1;return T;}else if(key < T-> data.key)return SearchBST(T-> lchild,key);elsereturn SearchBST(T-> rchild,key);}void InsertBST(BSTree &T,ElemType E){if(!T)        //这个地方不能把if的顺序放到后面,我调试了下,貌似是优先判断是否为空,然后在操作......{BSTree s;s = new BSTNode;s ->data = E;s -> lchild = s -> rchild = NULL;T = s;}else if(E.key < T-> data.key)InsertBST(T-> lchild,E);else if(E.key > T-> data.key)InsertBST(T-> rchild,E);}void CreatBST(BSTree &T){ElemType e;T = NULL;cin>>e.key;while(e.key<999999){InsertBST(T,e);cin>>e.key;}}void DeleteBST(BSTree &T,int key)//delete函数没有调试,书上代码全都给出来了{BSTree f=NULL,p=T,s,q;while(p){if(p->data.key == key)break;else if(p->data.key>key)p = p -> lchild;elsep = p -> rchild;}if(!p)  return;if(p -> lchild && p -> rchild){q = p;s = p -> lchild;while(p -> lchild){q = s;s = s -> rchild;}if(q != p)      //这个地方按照书上给的那个图,可能会产生疑惑//书上给出的只是中序遍历后节点刚好是右子树的,还有一种就是没有右子树的情况......q -> rchild = s -> rchild;elseq -> lchild = s -> lchild;delete s;return;}else if(!p -> rchild){q = p;p = p ->lchild;}else if(!p ->lchild){q = p;p = p -> rchild;}if(!f) T = p;else if(q == f ->lchild)f ->lchild = p;else f ->rchild = p;delete q;}


 

后面的四种排序是最近讲的,这里就不提了
原理自己看看就明白

后面我推荐一片文章:数据结构心得

链接
http://blog.csdn.net/k183000860/article/details/42101783

 

0 0
原创粉丝点击