基于递归的折半查找
【注意】真的mid下标是begin+我想的mid!!!
#include<iostream>#define MAXSIZE 100using namespace std;void HalfSearch(int a[],int e,int begin,int end){if(end<=begin){cout<<"NO"<<endl;return;}int mid=begin+(end-begin)/2; //注意mid!!! if(a[mid]==e){cout<<"YES"<<endl;return;}else if(a[mid]<e){HalfSearch(a,e,mid+1,end); }else {//mid>eHalfSearch(a,e,begin,mid-1);}}int main(){int n;cin>>n;while(n!=0){int a[MAXSIZE];for(int i=0;i<n;i++)cin>>a[i];int e;cin>>e;HalfSearch(a,e,0,n-1);cin>>n;} return 0;
}
二叉排序树的判定
#include<iostream>using namespace std; typedef struct BiNode{char data;struct BiNode *lchild;struct BiNode *rchild;
}BiNode,*BiTree;void CreateTree(BiTree &T){char root;cin>>root;if(root=='#'){T=NULL;return; }T=new BiNode;T->data=root; CreateTree(T->lchild);CreateTree(T->rchild); }bool Check(BiTree T){if(T->lchild){if(T->data<T->lchild->data)return false;}if(T->rchild){if(T->data>T->rchild->data)return false;}return true;
}int main(){while(true){BiTree T;CreateTree(T);if(!T)break;if(Check(T))cout<<"YES"<<endl;else cout<<"NO"<<endl;}return 0;
}
二叉排序树的限定条件下的数据输出
(因为检测输出时最后一个位置不能有括号,所以用了一个tag引用来标记!)
#include<iostream>using namespace std; typedef struct BiNode{int data;struct BiNode *lchild;struct BiNode *rchild;
}BiNode,*BiTree;void CreateTree(BiTree &T,int data){if(!T){T=new BiNode;T->data=data;T->lchild=NULL;T->rchild=NULL;return;}else{if(data<T->data){CreateTree(T->lchild,data);}elseCreateTree(T->rchild,data);}}bool Check(BiTree T){if(T->lchild){if(T->data<T->lchild->data)return false;}if(T->rchild){if(T->data>T->rchild->data)return false;}return true;
}void MidTraverse(BiTree T,int x,int &tag){if(T){BiTree p=T;if(p->data<x){MidTraverse(p->rchild,x,tag);}else if(p->data>=x){MidTraverse(p->lchild,x,tag);if(tag==1)cout<<" ";cout<<p->data;if(tag==0)tag=1;MidTraverse(p->rchild,x,tag);}}}int main(){while(true){int n;cin>>n;if(n==0)break;BiTree T=NULL;int data;for(int i=0;i<n;i++){cin>>data;CreateTree(T,data);}int x;cin>>x;int tag=0;MidTraverse(T,x,tag);cout<<endl;}return 0;
}
————————————华丽的分界线:以下是大重点——————————
查找链表倒数第k个元素——快慢指针!
#include<iostream>using namespace std;typedef struct LNode{int data;struct LNode *next;
}LNode,*LinkList;void CreateList(LinkList &L,int n){LinkList t=L;for(int i=0;i<n;i++){LinkList p=new LNode;cin>>p->data;p->next=NULL;while(t->next)t=t->next;t->next=p;t=p;}
}void GetLastK(LinkList L,int k){LinkList slow=L->next;LinkList fast=L->next;int cnt=0; //往后移动k步 while(cnt<k){cnt++;fast=fast->next;}while(fast){slow=slow->next;fast=fast->next;}cout<<slow->data<<endl;
}int main(){int n;cin>>n;while(n!=0){LinkList L;L->next=NULL;CreateList(L,n);int k;cin>>k;GetLastK(L,k);cin>>n;}return 0;
}
数组的循环左移(真·循环+左移....)
#include<iostream>using namespace std;void MoveLeft(int *a,int len,int p){while(p!=0){p--;int tmp=a[0];for(int i=0;i<len;i++){a[i]=a[i+1];}a[len-1]=tmp;}
}void ShowArray(int *a,int len){for(int i=0;i<len;i++){cout<<a[i];if(i!=len-1)cout<<" ";}cout<<endl;
}int main(){int n;cin>>n;while(n!=0){int *a=new int[n];for(int i=0;i<n;i++)cin>>a[i];int p;cin>>p;MoveLeft(a,n,p);ShowArray(a,n);cin>>n;}return 0;
}
数组的主元素查询
#include<iostream>using namespace std;int FindMain(int *a,int n){//一共要进行n-1次 for(int i=0;i<n-1;i++){for(int j=0;j<n-i-1;j++){if(a[j]>a[j+1]){int t=a[j+1];a[j+1]=a[j]; a[j]=t;}}} int m=n/2-1;if(a[m]==a[m+1])return a[m];else return -1;
}void ShowArray(int *a,int len){for(int i=0;i<len;i++){cout<<a[i];if(i!=len-1)cout<<" ";}cout<<endl;
}int main(){int n;cin>>n;while(n!=0){int *a=new int[n];for(int i=0;i<n;i++)cin>>a[i];cout<<FindMain(a,n)<<endl;cin>>n;}return 0;
}
数组的分割
【思路】其实就是找较小的一半数组和较大的一半数组。找中位数的方法简单但笨。因此选择快速排序的思想,用枢轴变量
#include <stdio.h>
#define LEN 20000int FindMidPosition(int a[],int low,int high)
{int temp=a[low];while(1){while(low<high&&a[high]>=temp){high--;}if(low>=high){break;}a[low++]=a[high];while(low<high&&a[low]<=temp){low++;}if(low>=high){break;}a[high--]=a[low];}a[low]=temp;return low;
}void Divide(int a[],int start,int end,int n)
{int mid;while(start<end){mid=FindMidPosition(a,start,end);if(mid==n/2){break;}else if(mid<n/2){start=mid+1;}else{end=mid-1;}}
}void OutputArray(int a[],int start,int end)
{int i;for(i=start;i<=end-1;i++){printf("%d ",a[i]);}printf("%d\n",a[i]);
}int main()
{int n,i;while(1){scanf("%d",&n);if(n==0){break;}else{int a[LEN];for(i=0;i<n;i++){scanf("%d",&a[i]);}Divide(a,0,n-1,n);OutputArray(a,0,n/2-1);OutputArray(a,n/2,n-1);}}return 0;
}
二叉树的WPL计算
#include<iostream>
#include<stdio.h>
using namespace std;typedef struct BiNode{int data;struct BiNode *lchild;struct BiNode *rchild;
}BiNode,*BiTree;void CreateTree(BiTree &T){int data;cin>>data;if(data==0){T=NULL;return;}T=new BiNode;T->data=data;CreateTree(T->lchild);CreateTree(T->rchild);
}void WPL(BiTree &T,int &nowValue,int &pathlen){if(!T->lchild && !T->rchild){//遇到了叶子结点nowValue+=T->data*pathlen;return;}if(T->lchild){pathlen++;WPL(T->lchild,nowValue,pathlen);pathlen--;}if(T->rchild){pathlen++;WPL(T->rchild,nowValue,pathlen);pathlen--;}
}int main(){while(1){BiTree T;CreateTree(T);if(!T)break;int wpl=0;int len=0;WPL(T,wpl,len);cout<<wpl<<endl;}return 0;
}
奇偶链表的分割
【总结】这种要求O(1)空间复杂度的,需要有一个东西记录住头,还需要有一个穿针引线的指针,去按我们需要的顺序把结点重新穿起来
void Divide(LinkList &L){LinkList p=L,r=L->next;LinkList myL;LinkList q=myL; int cnt=1;while(r){if(cnt%2==0){q->next=r;q=r;}else{p->next=r;p=r;}r=r->next;cnt++;}q->next=NULL;p->next=myL->next;}
找出数组中和为目标值的两个数
#include<iostream>using namespace std;#define MAXSIZE 100void GetTwo(int a[],int n,int &p,int &q,int target){for(int i=0;i<n;i++){p=a[i];q=target-a[i];for(int j=0;j<n;j++)if(a[j]==q && i!=j){p=i;q=j;return;}}
}int main(){int n;cin>>n;while(n!=0){int a[n];for(int i=0;i<n;i++)cin>>a[i];int target;cin>>target;int p,q;GetTwo(a,n,p,q,target);cout<<p<<" "<<q<<endl;cin>>n;}
}
删除链表中的倒数第k个结点
#include<iostream>using namespace std;typedef struct LNode{int data;struct LNode *next;
}LNode,*LinkList;void CreateList(LinkList &L,int n){L->next=NULL;LinkList t=L;for(int i=0;i<n;i++){LinkList p=new LNode;cin>>p->data;p->next=NULL;while(t->next)t=t->next;t->next=p;t=p;}
}bool IsEmpty(LinkList L){if(L->next==NULL) return true;else return false;
}void PrintList(LinkList L){LinkList p=L->next;while(p){cout<<p->data;if(p->next)cout<<" ";p=p->next;}cout<<endl;
}//删除倒数第k个结点
void DeleteList(LinkList &L,int k){LinkList slow=L->next;LinkList fast=L->next;LinkList preSlow=L;int cnt=1;while(cnt<=k){cnt++;fast=fast->next;} while(fast){slow=slow->next;preSlow=preSlow->next;fast=fast->next;}preSlow->next=slow->next;if(IsEmpty(L))cout<<"The LinkList is Empty !"<<endl;elsePrintList(L);
}int main(){int n;cin>>n;while(n!=0){LinkList L;CreateList(L,n);int k;cin>>k;DeleteList(L,k);cin>>n;}return 0;
}
基于链表的两数之和
【总结】本题涉及了一个关于进位的事就是写成if 9XXX,不要害怕
#include<iostream>using namespace std;typedef struct LNode{int data;struct LNode *next;
}LNode,*LinkList;//头插法创建链表
void CreateList(LinkList &L,int n){L=new LNode;L->next=NULL;LinkList t=L;for(int i=0;i<n;i++){LinkList p=new LNode;cin>>p->data;p->next=NULL;p->next=t->next;t->next=p; }}bool IsEmpty(LinkList L){if(L->next==NULL) return true;else return false;
}void PrintList(LinkList L){LinkList p=L->next;while(p){cout<<p->data;if(p->next)cout<<" ";p=p->next;}cout<<endl;
}void Sum(LinkList &L1,LinkList &L2,LinkList &L3){LinkList p1=L1->next;LinkList p2=L2->next;LinkList p3=L3;int c=0; //用来储存进位 while(p1 && p2){int sum=p1->data+p2->data+c;if(sum>=10){sum-=10;c=1;} else c=0;LinkList node=new LNode;node->data=sum;node->next=NULL;p3->next=node;p3=node;p1=p1->next;p2=p2->next;}if( p1 && p1->data==9 && c==1){LinkList node1=new LNode;node1->data=0;LinkList node2=new LNode;node2->data=1;node1->next=node2;node2->next=NULL;p3->next=node1;}else if( p2 &&p2->data==9 && c==1){LinkList node1=new LNode;node1->data=0;LinkList node2=new LNode;node2->data=1;node1->next=node2;node2->next=NULL;p3->next=node1;}else if(c==1){LinkList node=new LNode;node->data=1;node->next=NULL;p3->next=node;}
}int main(){int m,n;cin>>m>>n;while(n!=0 && m!=0){LinkList L1;CreateList(L1,m);LinkList L2;CreateList(L2,n);LinkList myL;myL->next=NULL;Sum(L1,L2,myL);PrintList(myL);cin>>m>>n;}return 0;
}
交换链表中的两个结点
【注】有时候的交换其实就是值的交换,不用捣腾指针,而且注意更改指针后,后移不要盲目的想成p=p->next
#include<bits/stdc++.h>
using namespace std;
typedef struct Lnode {int data;struct Lnode *next;
} Lnode, *Linklist;void Init_Linklist(Linklist &l) {l = new Lnode;l->next = NULL;
}void CreatLinklist(Linklist &l, int n) {Linklist p = l;Linklist r;for (int i = 1; i <= n; i++) {r = new Lnode;cin >> r->data;r->next = p->next;p->next = r;p = r;}
}void Exchange(Linklist &l) {Linklist p = l->next;while (p) {if(p->next != NULL){swap(p->data, p->next->data);p = p->next->next;}else{break;}}
}void Out(Linklist &l) {Linklist p = l->next;while (p->next) {cout << p->data << " ";p = p->next;}cout << p->data << endl;
}
int main() {while (1) {int n;cin >> n;if (n == 0) break;Linklist l;Init_Linklist(l);CreatLinklist(l,n);Exchange(l);Out(l);}return 0;
}
链表的循环右移(这个没有要头结点。先成环,再去掉链接)
#include<iostream>using namespace std;typedef struct LNode{int data;struct LNode *next;
}LNode,*LinkList;//创建链表
void CreateList(LinkList &L,int n){L=new LNode;L->next=NULL;cin>>L->data;LinkList t=L;for(int i=0;i<n-1;i++){LinkList p=new LNode;cin>>p->data;p->next=NULL;t->next=p;t=p; }}void Move(LinkList &L,int k){LinkList cur=L;int cnt=1;while(cur->next){cur=cur->next;cnt++;}cur->next=L;int m=cnt-k%cnt;for(int i=0;i<m;i++)cur=cur->next;LinkList newp=cur->next;cur->next=NULL;L=newp;
}void PrintList(LinkList L){LinkList p=L;while(p){cout<<p->data;if(p->next)cout<<" ";p=p->next;}cout<<endl;
}int main(){int n;cin>>n;while(n!=0){LinkList L;CreateList(L,n);int k;cin>>k;Move(L,k);PrintList(L);cin>>n;}return 0;
}
查找数组中缺失的数字
#include<iostream>using namespace std;void FindNum(int a[],int n){int ans[n];for(int i=0;i<n;i++){int index=(a[i]-1)%n;a[index]+=n;}int k=0;for(int i=0;i<n;i++){if(a[i]<=n){ans[k]=i+1;k++;}}for(int i=0;i<k;i++){cout<<ans[i];if(i!=k-1)cout<<" "; }if(k==0)cout<<"Not Found" ;cout<<endl;}int main(){int n;cin>>n;while(n!=0){int a[n];for(int i=0;i<n;i++){cin>>a[i];} FindNum(a,n);cin>>n; }return 0;
}