基于递归的折半查找
【注意】真的mid下标是begin+我想的mid!!!
cpp
#include<iostream>
#define MAXSIZE 100
using 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>e
HalfSearch(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;
}
二叉排序树的判定
cpp
#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引用来标记!)
cpp
#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);
}
else
CreateTree(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个元素------快慢指针!
cpp
#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;
}
数组的循环左移(真·循环+左移....)
cpp
#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;
}
数组的主元素查询
cpp
#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;
}
数组的分割
【思路】其实就是找较小的一半数组和较大的一半数组。找中位数的方法简单但笨。因此选择快速排序的思想,用枢轴变量
cpp
#include <stdio.h>
#define LEN 20000
int 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计算
cpp
#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)空间复杂度的,需要有一个东西记录住头,还需要有一个穿针引线的指针,去按我们需要的顺序把结点重新穿起来
cpp
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;
}
找出数组中和为目标值的两个数
cpp
#include<iostream>
using namespace std;
#define MAXSIZE 100
void 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个结点
cpp
#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;
else
PrintList(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,不要害怕
cpp
#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
cpp
#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;
}
链表的循环右移(这个没有要头结点。先成环,再去掉链接)
cpp
#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;
}
查找数组中缺失的数字
cpp
#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;
}