《剑指offer》练习

来源:互联网 发布:java socket 数据传输 编辑:程序博客网 时间:2024/06/14 07:22

3二维数组查找

#include<stdio.h>typedef int ElemType[][4];// 二维数组matrix中,每一行都从左到右递增排序,// 每一列都从上到下递增排序bool find(ElemType r,int rows,int cols,int key){bool isFound = false;if(r!=NULL && rows>0 && cols>0){//检查参数是否合法 int row = 0;int col = cols - 1; while(row<rows && col>=0){//循环最后的终止条件 if(r[row][col] == key){//命中 isFound = true;printf("命中\n");break;}else if(r[row][col]>key){//如果这一列最小值都比key大那么消除该列 col--;}else{row++;//如果改行的最大值都比key小那么消除该行}} }return isFound; }//  1   2   8   9//  2   4   9   12//  4   7   10  13//  6   8   11  15// 要查找的数在数组中int main(){int key = 50; ElemType r = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};bool isFound = find(r,4,4,key);printf("查找%d是否查找到:%3d\n",key,isFound);return 0;} 

4替换空格

#include<stdio.h>#include<stdlib.h>//把字符串中的空格替换成%20,在原字符串的基础上进行替换改变原来的值 //思路:从后向前替换:原尾指针、新尾指针->逐个后移->如果为空格新尾指针向前移动3个位置 //时间复杂度:O(n) void replaceBlank(char string[]){if(string == NULL){  //参数判断 return ;} int originalLength,newLength;//original字符串原长度,newLength替换后的字符串长度 int numberofBlank=0;//字符串中空格的个数 int indexofOriginal,indexofNew; //原字符串中的最后一个指针位置,新字符串中最后一个字符串的位置 originalLength = newLength = indexofOriginal = indexofNew = 0;//初始化变量 int i = 0;while(string[i] != '\0'){ if(string[i] == ' '){numberofBlank++; //计算字符串中空格字符的个数 }originalLength++;//计算源字符串的长度 i++;}if(originalLength <= 0){ //进行长度过滤 return ;}  newLength = originalLength + 2 * numberofBlank; //新字符串的长度  indexofOriginal = originalLength;indexofNew = newLength; while(originalLength>=0 && indexofNew>indexofOriginal){if(string[indexofOriginal] == ' '){//如果为空格新尾指针前移3三个位置 string[indexofNew--] = '0'; string[indexofNew--] = '2'; string[indexofNew--] = '%'; } else{string[indexofNew--] = string[indexofOriginal];//正常字符逐位后移 }indexofOriginal--;//原尾指针每次向前移动一位  } } // 打印void print(char string[]){int i= 0;while(string[i] != '\0'){printf("%c",string[i]); i++;} printf("\n");} int main(){char string[] = "I am a luckly boy!";printf("进行空格替换前:");print(string); printf("进行替换空格后:");replaceBlank(string);print(string); return 0;} 

5从尾到头打印链表

#include<stdio.h>#include<Stack>//引入栈 using namespace std;//用栈文件必须使用命名空间 //定义链表结构typedef struct Node{int data;struct Node *next;} Node,*P_Node;//打印void print(P_Node L){P_Node p = L->next;while(p){printf("%3d",p->data);p = p->next;} printf("\n");} //初始化void init(P_Node &L){L = (P_Node)malloc(sizeof(Node));if(L == NULL){printf("初始化失败\n");return ; }L->data = 0;L->next = NULL;} //创建链表void createTail(P_Node L,int n) {int i = 0;P_Node r = L;for(i=0;i<n;i++){P_Node newNode = (P_Node)malloc(sizeof(Node));if(newNode == NULL){printf("创建链表失败\n");return ;}newNode->data = i+1;newNode->next = r->next;r->next = newNode;r = newNode;L->data++; }printf("链表创建成功!\n"); }//使用栈——从尾到头打印链表void reserve1(P_Node L){stack<P_Node> Stack;P_Node p = L->next;while(p){Stack.push(p);p = p->next;}while(!Stack.empty()){p = Stack.top();Stack.pop();printf("%3d",p->data);}printf("\n");} //使用递归——从尾到头打印链表void reserve2(P_Node p){if(p != NULL){if(p->next != NULL){reserve2(p->next);}printf("%3d",p->data);}} int main(){P_Node L;int n = 5;init(L);createTail(L,n); print(L); //从尾到头输出reserve1(L); //用栈reserve2(L->next); //用递归  printf("\n"); return 0;} 

8旋转数组中的最小值

#include<stdio.h>typedef int ElemType[5];//打印void print(ElemType r,int n){int i = 0;for(i=0;i<n;i++){printf("%3d",r[i]); } printf("\n");} //顺序查找void minInOrder(ElemType r,int indexPre,int indexAfter) {int i = 0;int min = r[indexPre];for(i = indexPre;i<=indexAfter;i++){if(r[i]<min){min = r[i];break;}} printf("该旋转数组中的最小值是:%d在第%d位置上\n",min,i+1);}//查找旋转数组中的最小值void min(ElemType r,int length){int indexPre,indexAfter,indexMid;indexPre = 0;indexAfter = length-1;indexMid = indexPre; //此处和while中的条件是为了应对数组旋转数量为0即没有任何旋转 r[] = {1,2,3,4,5} while(r[indexPre]>=r[indexAfter]){if(indexAfter-indexPre == 1){indexMid = indexAfter;}indexMid = (indexPre+indexAfter)/2;//如果indexPre、idnexAfter、indeMid三个数相等时,则必须用顺序查找if(r[indexPre] == r[indexAfter] && r[indexPre] == r[indexMid]){minInOrder(r,indexPre,indexAfter);return ;}if(r[indexMid]>=r[indexPre]){indexPre = indexMid;}else if(r[indexMid]<=r[indexAfter]){indexAfter = indexMid;}} printf("该旋转数组中的最小值是:%d在第%d位置上\n",r[indexMid],indexMid+1); } //计算从1加到n;//递归实现1+2+3..+n;int add1(int n){return (n<=0) ? 0 : n+add1(n-1); } //遍历实现1+2+3...+n;int add2(int n){int i =1;int result = 0; for(i=1;i<=n;i++){result  = result + i;} return result;} int main(){int n = 5;ElemType r = {2,3,4,5,1}; //测试特例:r[] = {1,0,1,1,1};r[] = {1,1,1,0,1}; print(r,n);min(r,n);printf("旋转数组中的最小值!\n");printf("\n\n");n = 100;printf("递归实现:1+2+3...+n = %3d\n",add1(n)); //递归 printf("遍历实现:1+2+3...+n = %3d\n",add2(n)); //遍历 return 0;} 

11数值的整数次方

#include<stdio.h>double getPower(double base,unsigned int ex){if(ex == 0)return 1.0;if(ex == 1)return base;double result = getPower(base,ex>>1);//这里使用左移一位代替除2操作 result = result*result;  //result^2,对计算的结构在进行平方操作if(ex & 0x1 == 1){//这里使用了与运算来代替%取余运算 result = result * base; //如果ex实奇数则最后再乘以一个base } return result; } //求数值的整数次方double power(double base,unsigned int ex){if(base == 0.0){ //如果base为0则结果为0; return 0.0;}unsigned int ex_bak = (unsigned int)(ex);if(ex<0){ ex_bak = (unsigned int) (-ex);//注意此处无符号整数取负数 } double result = getPower(base,ex_bak);if(ex<0){result = 1.0/result;//如果指数是负数则进行倒数 } return result;}int main(){double base  = -2;unsigned int ex =10  ;printf("%lf的%u次方为:%lf\n",base,ex,power(base,ex));return 0;} 

14调整数组顺序奇数位于偶数前面

#include<stdio.h>//定义结构体 typedef int ElemType[5];//打印void print(ElemType r,int length){int i =0;for(i=0;i<length;i++){printf("%3d",r[i]);} printf("\n");} //重新定位位置,是奇数位于偶数的前面 void ReOrder(ElemType r,int length){if(r==NULL || length<=0){return ;}int indexPre = 0;int indexAfter = length-1;while(indexPre<indexAfter){while(indexPre<indexAfter && (r[indexPre]&0x1) == 1)indexPre++; //使用&运算符是注意要加上括号,优先级问题  while(indexPre<indexAfter && (r[indexAfter]&0x1) != 1)indexAfter--;if(indexPre<indexAfter){int tmp = r[indexPre];r[indexPre] = r[indexAfter];r[indexAfter] = tmp;}}}int main(){int n = 5;ElemType r ={1,2,3,4,5}; print(r,n);ReOrder(r,5);print(r,n); printf("调整数组顺序是奇数位于偶数前面!\n"); return 0;} 

15链表中倒数第k个节点

#include<stdio.h>#include<stdlib.h>//定义链表结构 typedef struct Node{int data;struct Node *next;}Node,*P_Node; //打印void print(P_Node L){P_Node p = L->next;while(p){printf("%3d",p->data);p = p->next;}printf("\n");} //初始化void init(P_Node &L){L  = (P_Node)malloc(sizeof(Node));if(L == NULL){printf("初始化失败!\n");return ;}L->data = 0;L->next = NULL; printf("初始化成功!\n");} //创建单链表void createTail(P_Node L,int n ){int i = 0; P_Node r = L;for(i=0;i<n;i++){P_Node newNode = (P_Node)malloc(sizeof(Node));if(newNode == NULL){printf("创建失败!\n");return ;}newNode->data = i+1;newNode->next = r->next;r->next = newNode;r = newNode;L->data++;}printf("创建成功!\n");} //找到倒数第K个节点void find(P_Node L,int k){int i = 0;if(L == NULL || L->next == NULL || k <= 0){//判断链表是否为空return ;} P_Node fast = L->next;P_Node slow = L->next;for(i=1;i<k;i++){ if(fast->next != NULL){//判断k是否大于链表的长度 fast = fast->next;}else{return ;}}while(fast->next != NULL){ //快的和慢的一块移动,么次移动一个位置。 fast = fast->next;slow = slow->next;} printf("链表中倒数第%d个位置是:%3d\n",k,slow->data); } //查找链表的中间节点(节点数为偶数时候,取中间两个中的任意一个) void findMid(P_Node L){if(L == NULL || L->next == NULL){return ;} P_Node fast,slow;//快指针一次走两步,慢指针一次走一步,当快指针走到尾部时慢指针的位置就是链表中的中间位置, fast = slow = L->next;//开始时候快指针和慢指针都在第一个结点的位置while(fast->next!= NULL && fast->next->next != NULL){ fast = fast->next->next;slow = slow->next; }printf("链表的中间节点是:%3d\n",slow->data);}//判断链表中是否又环void ajustRing(P_Node L){if(L==NULL || L->next == NULL){ //参数过滤 return ;} P_Node fast,slow;fast = slow = L->next;while(fast->next != slow && fast->next != NULL){fast = fast->next->next;slow = slow;}printf("该链表中存在环!\n");} int main(){int n = 9;int k = 3 ;P_Node L;init(L);createTail(L,n);print(L);find(L,k);//查找链表中倒数第K个节点findMid(NULL); //查找链表中的中间节点 ajustRing(L);return 0;} 

16反转链表

#include<stdio.h>#include<stdlib.h>//定义结构体typedef struct Node{int data;struct Node *next;} Node,*P_Node;//打印void print(P_Node L){if(L == NULL){return ;} P_Node p = L->next;    while(p != NULL){        printf("%3d",p->data);        p = p->next;    }           printf("\n"); }//初始化void init(P_Node &L){if(L == NULL){return ;}L = (P_Node)malloc(sizeof(Node));if(L == NULL){printf("初始化失败\n");return ;}L->data = 0;L->next = NULL;printf("初始化成功!\n"); } //创建链表void createTail(P_Node L, int n){if(L == NULL){return ;}int i = 0;P_Node r,newNode;r = L; for(i=0;i<n;i++){newNode = (P_Node)malloc(sizeof(Node)); if(newNode == NULL){ printf("创建链表失败!\n"); return ; } newNode->data = i+1;newNode->next = r->next;r->next = newNode;r = newNode;L->data++; }printf("链表创建成功!\n"); } //反转链表void reverse(P_Node L){if(L == NULL){return;}P_Node preNode,curNode,nextNode;preNode = L->next;curNode = preNode->next;while(curNode!=NULL){nextNode = curNode->next;curNode->next = preNode;preNode = curNode;curNode = nextNode;} L->next->next = NULL;L->next = preNode;} int main(){int n = 10;P_Node L;init(L);//初始化 createTail(L,n);print(L);reverse(L); //反转链表 print(L);//printf("反转链表!\n");return 0;} 

17合并两个排序链表

#include<stdio.h>#include<stdlib.h>//定义结构体typedef struct Node{int data;struct Node *next;} Node,*P_Node;//打印void print(P_Node L){if(L == NULL){return ;} P_Node p = L->next;    while(p != NULL){        printf("%3d",p->data);        p = p->next;    }           printf("\n"); }//初始化void init(P_Node &L){if(L == NULL){return ;}L = (P_Node)malloc(sizeof(Node));if(L == NULL){printf("初始化失败\n");return ;}L->data = 0;L->next = NULL;printf("初始化成功!\n"); } //创建链表void createTail(P_Node L, int n,int type){if(L == NULL){return ;}int i = 0;P_Node r,newNode;r = L; for(i=0;i<n;i++){newNode = (P_Node)malloc(sizeof(Node)); if(newNode == NULL){ printf("创建链表失败!\n"); return ; } if(type ==0){newNode->data = 2*(i+1)-1; }else{ newNode->data = 2*(i+1); } newNode->next = r->next;r->next = newNode;r = newNode;L->data++; }printf("链表创建成功!\n"); } //合并两个排序链表P_Node Merge(P_Node p1,P_Node p2){if(p1 == NULL)return p2;if(p2 == NULL)return p1; P_Node head;if(p1->data<p2->data){head = p1;head->next = Merge(p1->next,p2);}else{head = p2;head->next = Merge(p2->next,p1); }return head;} int main(){int n = 5;int type = 0;P_Node L1,L2;//L1=1,3,5,7,9init(L1);//初始化 type = 0;createTail(L1,n,type);printf("L1:"); print(L1);//L2init(L2);//初始化 n = 4;type = 1;createTail(L2,n,type);printf("L2:"); print(L2);//合并两个排序链表P_Node res = (P_Node)malloc(sizeof(Node));res->next = Merge(L1->next,L2->next); printf("\n合并后:"); print(res);return 0;} 

18树的子树

#include<stdio.h>#include<stdlib.h>#include<stack>using namespace std;//定义树结构 typedef struct Node{char data;struct Node *Lchild;struct Node *Rchild; } Node,*P_Node;//创建树-前序遍历,输入:AB#D##C## void create(P_Node &T){char data;scanf("%c",&data);if(data=='#'){T = NULL;return ; }else{ T = (P_Node)malloc(sizeof(Node));if(T == NULL){printf("创建失败!\n");return ;}T->data = data;create(T->Lchild);create(T->Rchild);}} //前序遍历void preOrder(P_Node T){if(T == NULL){return ;}else{printf("%c",T->data);preOrder(T->Lchild);preOrder(T->Rchild);}} //中序遍历void midOrder(P_Node T){if(T == NULL){return ;}else{midOrder(T->Lchild);printf("%c",T->data);midOrder(T->Rchild);}} //后序遍历void afterOrder(P_Node T){if(T == NULL){return ;}else{afterOrder(T->Lchild);afterOrder(T->Rchild);printf("%c",T->data);}} //非递归前序遍历 void pre(P_Node T){stack<P_Node> Stack;while(T || !Stack.empty()){while(T){printf("%c",T->data);Stack.push(T);T = T->Lchild;}T = Stack.top();Stack.pop();T = T->Rchild;}}//非递归中序遍历void mid(P_Node T){stack<P_Node>Stack;while(T || !Stack.empty()){while(T){Stack.push(T);T = T->Lchild;}T = Stack.top();printf("%c",T->data);Stack.pop();T = T->Rchild;}} //非递归后序遍历void after(P_Node T){    stack<P_Node> Stack;    P_Node pCur; //定义指针,指向当前节点      P_Node pPre = NULL;//定义指针,指向上一各访问的节点      Stack.push(T);    while(!Stack.empty()){        pCur = Stack.top();        //如果当前节点没有左右孩子,或者有左孩子或有孩子,但已经被访问输出,          //则直接输出该节点,将其出栈,将其设为上一个访问的节点          if((pCur->Lchild==NULL && pCur->Rchild == NULL) ||        (pPre != NULL && (pCur->Lchild==pPre || pCur->Rchild == pPre))){            printf("%c",pCur->data);            Stack.pop();            pPre = pCur;        }else{            //如果不满足上面两种情况,则将其右孩子左孩子依次入栈              if(pCur->Rchild != NULL)                  Stack.push(pCur->Rchild);              if(pCur->Lchild != NULL)                 Stack.push(pCur->Lchild);        }    }} //查找子树bool findSubTree(P_Node TRoot,P_Node T2Root){if(T2Root == NULL) return true;if(TRoot == NULL) return false;if(TRoot->data != T2Root->data)return false; return findSubTree(TRoot->Lchild,T2Root->Lchild) && findSubTree(T2Root->Rchild,T2Root->Rchild);} //判断是不是T2是不是T的子树bool isSubTree(P_Node T,P_Node T2){bool isTrue = false;if(T !=NULL && T2 != NULL){if(T->data == T2->data)isTrue = findSubTree(T,T2);if(!isTrue)isTrue = isSubTree(T->Lchild,T2);if(!isTrue)isTrue = isSubTree(T->Rchild,T2);}return isTrue;} int main(){P_Node T;create(T); //输入AB#D##C## printf("\n------------------------递归遍历-------------------------\n"); printf("前序遍历:");preOrder(T);printf("\n中序遍历:");midOrder(T);printf("\n后续遍历:"); afterOrder(T); printf("\n-----------------------非递归遍历-------------------------\n"); printf("\n非递归前序遍历:");pre(T);printf("\n非递归中序遍历:");mid(T);printf("\n非递归后序遍历:");after(T);printf("\n\n--------------判断B#D##是不是AB#D##C##的子树---------------\n"); //fflush(stdin);getchar();P_Node T2;create(T2); //是子树:B#D##;不是子树: BD### preOrder(T2); bool isFound = isSubTree(T,T2); printf("\nT2是否是T的子树:%d\n",isFound); printf("\n");return 0;} 

19二叉树的镜像

 #include<stdio.h> #include<stdlib.h> #include<stack> using namespace std; //定义树的结构 typedef struct Node { int data; struct Node *Lchild; struct Node *Rchild; } Node,*P_Node;  //创建树 void createTree(P_Node &T){ int data; scanf("%d",&data); if(data == 0){ T = NULL; return ; }else{ T = (P_Node)malloc(sizeof(Node)); T->data = data; createTree(T->Lchild);createTree(T->Rchild); } } //前序遍历 void preOrder(P_Node T){if(T == NULL){return ;}else{printf("%3d",T->data);preOrder(T->Lchild);preOrder(T->Rchild);} }  //非递归前序遍历 void pre(P_Node T){ stack<P_Node>Stack; while(T || !Stack.empty()){while(T){printf("%3d",T->data);Stack.push(T);T = T->Lchild;}T = Stack.top();Stack.pop();T = T->Rchild;} }  //树的镜像void treeMirror(P_Node T){if(T == NULL)return; //T传入的是NULL if(T->Lchild==NULL && T->Rchild==NULL)return; //T只有一个节点 P_Node tmp;//交换左右子树 tmp = T->Lchild;T->Lchild = T->Rchild;T->Rchild = tmp;treeMirror(T->Lchild);//递归左子树 treeMirror(T->Rchild);//递归右子树 } //非递归实现树的镜像 void treeMirror2(P_Node T){stack<P_Node>Stack; while(T || !Stack.empty()){while(T){if(!(T == NULL) && !(T->Lchild==NULL && T->Rchild==NULL)){P_Node tmp;//交换左右子树 tmp = T->Lchild;T->Lchild = T->Rchild;T->Rchild = tmp;}Stack.push(T);T = T->Lchild;}T = Stack.top();Stack.pop();T = T->Rchild;}} int main(){ P_Node T; createTree(T);  printf("\n");preOrder(T);printf("\n");pre(T);printf("\n");//输出树的镜像treeMirror2(T);preOrder(T); printf("\n");                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         }

23从上往下打印二叉树

#include<stdio.h>#include<queue> //引入队列文件 using namespace std;//定义树结构typedef struct Node{char data;struct Node *Lchild;struct Node *Rchild; } Node,*P_Node;//创建树void createTree(P_Node &T){char data;scanf("%c",&data);if(data == '#'){T = NULL;return ; }else{T = (P_Node)malloc(sizeof(Node));if(T == NULL){printf("创建失败!\n");return ;}T->data = data;createTree(T->Lchild);createTree(T->Rchild); }} //前序遍历void preOrder(P_Node T){if(T == NULL){return ;}else{printf("%c",T->data);preOrder(T->Lchild);preOrder(T->Rchild); }} //从上到下打印二叉树,基层序遍历 void TBOrder(P_Node T){queue<P_Node>TQueue;  //定义一个队列 TQueue.push(T);while(!TQueue.empty()){T = TQueue.front(); //获取队首 TQueue.pop();//出队队首 printf("%c",T->data);if(T->Lchild)TQueue.push(T->Lchild);//如果有左子树,左子树入栈 if(T->Rchild)TQueue.push(T->Rchild); //如果有右子树,右子树入栈 }} int main(){P_Node T;createTree(T);preOrder(T);printf("\n");TBOrder(T);printf("\n"); printf("Hello world !\n");return 0;} 

24二叉搜索树的后序遍历序列

#include<stdio.h>#include<stdlib.h>//验证一个数组是不是一棵树的后序遍历序列 bool verifyBST(int r[],int length){if(r == NULL || length <= 0){return false ;}int root  = r[length-1]; //取出根节点 int i = 0;for(i=0;i<length-1;i++){ //计算左子树的长度 ,并判断左子树是否满足二叉搜索树的定义 if(r[i]>root)break; }int j = i;for(j=i;j<length-1;j++){//计算右子树的长度,并判断右子树是否满足二叉搜索树的定义 if(r[j]<root)return false;}bool left = true;if(i>0){ left = verifyBST(r,i); //递归判断左子树部分 }bool right = true;if(i<length-1){right = verifyBST(r+i,length-i-1);//递归判断右子树部分(后边多减去1是把根节点位置减掉) }return (left && right);} int main(){int r[]={5,7,6,9,11,10,8};bool isTrue = verifyBST(r,7); printf("r[]={5,7,6,9,11,10,8}是否是二叉搜索树的后续遍历序列:%3d\n",isTrue);printf("二叉搜索树的后序遍历序列\n");return 0;} 

25二叉树中和为某一值得路径

#include<stdio.h>#include<stdlib.h>#include<stack>#include<vector>using namespace std;//定义树结构typedef struct Node{int data;struct Node *Lchild;struct Node *Rchild; } Node,*P_Node;//创建树void createTree(P_Node &T){int data;scanf("%d",&data);if(data == 0) {T = NULL;}else{T = (P_Node)malloc(sizeof(Node));if(T == NULL){printf("创建树失败!\n");return ;}T->data = data;createTree(T->Lchild);createTree(T->Rchild);}} //递归前序遍历void preOrder(P_Node T){if(T == NULL){return ;}else{printf("%5d",T->data);preOrder(T->Lchild);preOrder(T->Rchild);}} //findPathvoid findPath(P_Node T,int sum){if(T == NULL){return ;} stack<P_Node>Stack; vector<int>Vector;int currentSum = 0;bool isEqual = false;bool isLeaf = false;while(T || !Stack.empty()){while(T){Stack.push(T);Vector.push_back(T->data);currentSum = currentSum + T->data; isEqual =  (currentSum == sum);//当前值是否等于查找的和 //isLeaf = (T->Lchild == NULL && T->Rchild == NULL);//是否叶子节点 vector<int>::iterator it;if(isEqual && isLeaf){printf("s");for(it=Vector.begin();it!=Vector.end();it++)    printf("%3d->",*it);printf("\n");} printf("\n");printf("%5d",currentSum);T = T->Lchild; } T = Stack.top();Vector.pop_back();Stack.pop();T = T->Rchild;}}int main(){P_Node T;createTree(T);printf("\n");preOrder(T);printf("\n");findPath(T,22);printf("\n");printf("二叉树中和为某一值的路径!\n");return 0; } 

28字符串的排列

#include<stdio.h>#include<stdlib.h>//递归执行排列void doPL(char* str, char* begin){if(*begin == '\0'){printf("%s\n",str);}else{for(char* ch=begin;*ch != '\0';++ch){char tmp = *ch;*ch = *begin;*begin = tmp;doPL(str,begin+1);tmp = *ch;*ch = *begin;*begin = tmp;} } } //字符串的排列void PL(char* str){if(str == NULL)return;doPL(str,str);} int main(){char str[] = "abc";printf("字符串%s的排列:\n",str);PL(str);printf("字符串的排列!\n");return 0;} 

29出现次数超过一半的数

#include<stdio.h>typedef int ElemType[10];//打印void print(ElemType r,int length){int i = 0;for(i=0;i<length;i++){printf("%3d",r[i]);}printf("\n");} //交换void swap(ElemType r,int low,int high){int tmp = r[low];r[low] = r[high];r[high] = tmp; } //获取元素位置int partition(ElemTyper,int low,int high){int privotKey = r[low];while(low<high){while(low<high && r[high]>=privotKey)high--;swap(r,low,high);while(low<high && r[low]<=privotKey)low++;swap(r,low,high);}return low;} //检查数组是否合法bool verifyArray(ElemType r,int length){if(r == NULL && length<=0){return false;}return true;}//验证中间数是否超过数组元素的一半 bool verifyMidNumber(ElemType r,int length,int number){int i,times;i = times = 0;for(i=0;i<length;i++){if(r[i]==number)times++;}if(2*times<=length){return false;}else{return true;}}//获取中间元素void findNumber(ElemType r,int length){if(!verifyArray(r,length)){return ;}int low = 0;int high = length-1;int mid = high>>1; //此处用位移操作代替/2int index = partition(r,low,high);while(index != mid){if(index>mid){high = index-1;index = partition(r,low,high);}else{low = index+1;index = partition(r,low,high);}}  int midNumber = r[mid]; if(verifyMidNumber(r,length,midNumber)){printf("数组中出现次数超过一半的数是:%d\n",midNumber);  }else{ printf("数组中出现次数超过一半的数是:不存在!\n"); }} //获取中间元素2不修改原数组 void findNumber2(ElemType r,int length){if(!verifyArray(r,length))return ;int result = r[0];int times = 1;int i = 0;for(i=1;i<length;i++){if(times == 0)result  = r[i];if(r[i] == result) {times++;} else{times--;}} if(verifyMidNumber(r,length,result)){printf("数组中出现次数超过一半的数是:%d\n",result);  }else{ printf("数组中出现次数超过一半的数是:不存在!\n"); }} int main(){ElemType r ={6,6,3,2,2,6,6,4,6};int length = 9;void print(ElemType,int );//打印数组 int partition(ElemType,int ,int ); //获取元素的位置bool verifyMidNumber(ElemType,int ,int );//验证获取的中间数是否超过数组长度的一半 void findNumber(ElemType,int); //获取中间元素的位置bool verifyArray(ElemType,int ); //验证数组是否合法 print(r,length);//findNumber(r,length);//使用partition 改变原数组 findNumber2(r,length);//不改变原来的数组 print(r,length);printf("数组中出现次数超过一半的数\n");return 0; }

30最小的k个数

#include<stdio.h>typedef int ElemType[10];//打印void print(ElemType r,int length){int i =0;for(i=0;i<length;i++){printf("%3d",r[i]);}printf("\n");} //交换void swap(ElemType r,int low,int high){int tmp = r[low];r[low] = r[high];r[high] = tmp; } //获取元素位置int partition(ElemType r,int low,int high){int privotKey = r[low];while(low<high){while(low<high && r[high]>=privotKey)high--;swap(r,low,high);while(low<high && r[low]<=privotKey)low++;swap(r,low,high);}return low;} //查找最小的k个元素void find(ElemType r,int length, int k){int low = 0;int high = length - 1;int index = partition(r,low,high);while(index != k-1){if(index>k-1){high = index - 1;index = partition(r,low,high);}else{low = index + 1;index = partition(r,low,high);}}print(r,k); //打印出最小的k个数 } int main(){int k = 6;int length = 9;ElemType r = {9,6,7,8,5,1,2,3,4};print(r,length);//原始数组 find(r,length,k);  //打印最小的k个数 printf("最小的k个数\n");return 0;} 

32连续子数组的最大和

#include<stdio.h>//连续子数组中的最大和void subArrayMax(int r[],int length){int currSum,maxSum;currSum = maxSum = 0;for(int i=0;i<length;i++){if(currSum<=0){currSum = r[i];}else{currSum += r[i];}if(currSum>maxSum)maxSum = currSum; }printf("连续子数组中的最大和:%3d\n",maxSum);} int main(){int r[] = {1,-2,3,10,-4,7,2,-5};subArrayMax(r,8);printf("连续子数组中的最大和\n"); return 0;} 


33二分查找+快排

#include<stdio.h>typedef int ElemType[9];//打印void print(ElemType r,int n){int i = 0;for(i=0;i<n;i++){printf("%3d",r[i]);}printf("\n");} //交换值void swap(ElemType r,int low,int high){int tmp = r[low];r[low] = r[high];r[high] = tmp;} //partitionint partition(ElemType r,int low, int high){int privotKey = r[low];while(low<high){while(low<high && r[high]>=privotKey)high--;swap(r,low,high);while(low<high && r[low]<=privotKey)low++;swap(r,low,high);}return low;} //快速排序 int QSort(ElemType r,int low,int high){if(low<high){int privot = partition(r,low,high);QSort(r,low,privot-1);QSort(r,privot+1,high);} }//二分查找void binSearch(ElemType r,int low,int high,int key){while(low<=high){int mid = (low+high)/2;if(r[mid] == key){printf("命中!\n");return ;}else if(r[mid]>key){high = mid - 1;}else{low = mid + 1;}}printf("没有查找到!\n");} int main(){ElemType r ={4,3,6,8,9,7,5,1,2};int key = 15 ;print(r,9);QSort(r,0,8);print(r,9);printf("查找元素%d的结果:",key);binSearch(r,0,8,key);return 0;} 

34二进制中1的个数

#include<stdio.h>//二进中1的个数void numberOf1(int n){int flag = 1;int count = 0;while(flag){if(n & flag){count++ ;} flag = flag<<1;}printf("%3d中1的个数%3d\n",n,count);} void numberOf1x(int n){int tmp = n;int count = 0;while(n){++count;n = (n-1)&n;}printf("%3d中1的个数%3d\n",tmp,count);}int main(){int n = 10;numberOf1(n);numberOf1x(n);return 0;} 

35斐波那契数列

#include<stdio.h>//常规斐波那契数列-使用递归 int Feibonacci(unsigned int n){if(n <= 0){return 0;}if(n == 1){return 1;} return Feibonacci(n-1)+Feibonacci(n-2) ; } //使用遍历void Fei(unsigned int n){int res[2] = {0,1}; if(n < 2){printf("%3d",res[n]); //特殊情况 return ;} long long x = 0;long long y = 1;long long z = 0;unsigned int i = 0;for(i=2;i<=n;i++){z = x + y;x = y;y = z;}printf("%3lld\n",z);}  int main(){int n = 8;//printf("Feibonacci数列第%d个位置上是%d",n,Feibonacci(n));Fei(n);printf("\n斐波那契数列!\n");return 0;} 

36判断链表中是否存在环、环长度

#include<stdio.h>#include<stdlib.h>//定义结构体typedef struct Node{int data;struct Node *next;} Node,*P_Node;//打印void print(P_Node L){P_Node p = L->next;while(p != NULL && p != L){printf("%3d",p->data);p = p->next; }printf("\n");} // 初始化void init(P_Node &L){L = (P_Node)malloc(sizeof(Node));if(L == NULL){printf("初始化失败!\n");return ;}L->data = 0;L->next = L; //创建循环链表 } //创建链表void createTail(P_Node L,int n){int i = 0;P_Node r = L; for(i=0;i<n;i++){P_Node newNode = (P_Node)malloc(sizeof(Node));if(newNode == NULL){printf("创建链表失败!\n");return ;}newNode->data = i+1;newNode->next = r->next;r->next = newNode;r = newNode; L->data++;}} //判断链表中是否存在环void isLoop(P_Node L){if(L==NULL && L->next==NULL){//参数过滤 return ; } P_Node fast,slow;fast = slow = L->next;while(fast->next!=NULL && fast->next->next!=NULL){//循环判断 是否结束循环 fast = fast->next->next;slow = slow->next;if(fast == slow){break;} } if(fast==slow && slow!=NULL){//跳出循环后 判断是为NULL时跳出的循环还是faste = slow时跳出的循环 printf("该链表中存在环\n");}else{printf("该链表中不存在环\n");} } //判断链表中环的长度void loopLength(P_Node L){if(L==NULL || L->next==NULL){return ;}P_Node fast,slow;fast = slow = L->next;int length = 0;while(fast->next!=NULL && fast->next->next!=NULL){fast=fast->next->next;slow=slow->next;length++;//统计链表中环的长度 if(slow==fast){break;} } if(fast==slow && fast!=NULL){ printf("该链表中存在环,环的长度为(包含头结点):%3d\n",length);}else{printf("该链表不存在环!\n");}} int main(){int n = 10;P_Node L;init(L);createTail(L,n);print(L);isLoop(L);//判断链表中是否存在环 loopLength(L); //计算出链表中环的长度 return 0;} 

37汉诺塔(解析PPT)

#include <stdio.h> //诺塔的算法就3个步骤:第一,把a上的n-1个盘通过c移动到b。第二,把a上的最下面的盘移到c。第三,因为n-1个盘全在b上了,所以把b当做a重复以上步骤就好了。//第一个塔为初始塔,中间的塔为借用塔,最后一个塔为目标塔  int i=1;//记录步数  void move(int n,char from,char to){ //将编号为n的盘子由from移动到to  printf("第%d步:将%d号盘子%c---->%c\n",i++,n,from,to);  }  void hanoi(int n,char from,char denpend_on,char to){//将n个盘子由初始塔移动到目标塔(利用借用塔)      if (n==1){    move(1,from,to);//只有一个盘子是直接将初塔上的盘子移动到目的地      }else{hanoi(n-1,from,to,denpend_on);//先将初始塔的前n-1个盘子借助目的塔移动到借用塔上  move(n,from,to);              //将剩下的一个盘子移动到目的塔上  hanoi(n-1,denpend_on,from,to);//最后将借用塔上的n-1个盘子移动到目的塔上      }  }  int  main(){     printf("请输入盘子的个数:\n");       int n;       scanf("%d",&n);       char x='A',y='B',z='C';       printf("盘子移动情况如下:\n");       hanoi(n,x,y,z);            return 0;} 

38数组原地旋转90°

题目描述:
一个n×n的二维数组,原地顺时针旋转90度,注意是原地哦,就是不能申请其它的空间。

解析:
这个原地顺时针旋转90°可以看成经过两次变换得到,@四年之后是神 所说中沿着副对角线反转然后沿着水平中线反转是一种方法,还有一种是沿着主对角线反转之后沿着垂直反转也是一种方法。 依次类推,可以思考顺时针180°旋转是怎样变换得到的(水平和垂直反转各一次),逆时针90°(主对角线,水平或者副对角线,垂直)。矩阵的变化还蛮多的,小伙伴们可以多思考一下。 代码如下:
#include <iostream>#include <iomanip>using namespace std;#define MIX_ROW 8void initArr(int arr[][MIX_ROW],int row){  int i,j,temp=1;  for(i=0;i<row;i++){    for(j=0;j<row;j++){      arr[i][j]=temp++;    }  }}void printArr(int arr[][MIX_ROW],int row){  int i,j;  for(i=0;i<row;i++){    for(j=0;j<row;j++){      cout<<setw(2)<<arr[i][j]<<" ";    }    cout<<endl;  }  cout<<endl;}//矩阵顺时针旋转90度,可以认为先沿着主对角线做一个翻转,然后在做一个左右翻转即可//要原地变换,则交换操作不能申请临时变量,则,可以使用两种方法://a=a+b;b=a-b;a=a-b//a=a^b;b=a^b;a=a^bvoid rotateMix(int arr[][MIX_ROW],int row){  int i,j;  for(i=0;i<row-1;i++){    for(j=i+1;j<row;j++){      arr[i][j]+=arr[j][i];      arr[j][i]=arr[i][j]-arr[j][i];      arr[i][j]-=arr[j][i];    }  }  for(i=0;i<row/2;i++){    for(j=0;j<row;j++){      arr[j][i]+=arr[j][row-i-1];      arr[j][row-i-1]=arr[j][i]-arr[j][row-i-1];      arr[j][i]-=arr[j][row-i-1];    }  }}int main(int count,char*args[]){  int arr[MIX_ROW][MIX_ROW];  initArr(arr,MIX_ROW);  printArr(arr,MIX_ROW);  rotateMix(arr,MIX_ROW);  printArr(arr,MIX_ROW);  return 0;}

26复杂链表的复制

#include<stdio.h>#include<stdlib.h>typedef struct Node{int data;struct Node *next;struct Node *random;} Node,*P_Node;//打印void print(P_Node PHead){P_Node p = PHead;while(p){printf("%3d",p->data);p = p->next;}printf("\n");} //获取链表长度void length(P_Node PHead){P_Node p = PHead;int count = 0;while(p){count++;p = p->next;}printf("此时链表的长度为:%3\n",count);} //创建链表void create(P_Node &PHead, int length) {PHead = (P_Node)malloc(sizeof(Node));PHead->data = 1;PHead->next = NULL;PHead->random = PHead;P_Node p,newNode;p = PHead;for(int i=1;i<length;i++){newNode = (P_Node)malloc(sizeof(Node));newNode->data = i+1;newNode->next = p->next;newNode->random = newNode; p->next = newNode; p = newNode; } }// 复制节点void copy(P_Node PHead){P_Node p,cloneNode;p = PHead;while(p){cloneNode = (P_Node)malloc(sizeof(Node));cloneNode->next = p->next; p->next = cloneNode; p = cloneNode->next;}} //复制节点信息 void copyInfo(P_Node PHead){P_Node p,cloneNode;p = PHead;while(p){cloneNode = p->next;cloneNode->data = p->data;cloneNode->random = p->random->next;p = cloneNode->next;}} //拆分节点P_Node split(P_Node PHead){P_Node p,cloneHead,cloneNode;p = PHead;cloneHead = cloneNode = PHead->next;while(cloneNode->next != NULL){p->next = cloneNode->next;p = cloneNode->next;cloneNode->next = p->next;cloneNode = p->next; } p->next = NULL;return cloneHead;} int main(){P_Node PHead,cloneHead;create(PHead,5); //创建链表 copy(PHead);//复制链表结构(插在源节点后) copyInfo(PHead);// 复制链表信息(data,next,random) cloneHead = split(PHead); //拆分链表(奇:原链表;偶:链表副本) // 输出原链表print(PHead); // 输出clone的链表 print(cloneHead); }

27约瑟夫环

#include<stdio.h>#include<stdlib.h>//定义结构体typedef struct Node{int data;struct Node *next;} Node,*P_Node;//约瑟夫环(n为结点个数,m倍数,k开始位置) //思路:创建头结点->创建剩余的节点->移动到k位置上->移动到m-1位置上->出圈->循环 void josephusRing(int n,int m,int k){ P_Node curr,p,r;//curr为构建循环链表时的当前节点;p为进行判断时的当前节点;r为进行判断时的辅助节点;int i;//创建头结点即第一个节点 p = (P_Node)malloc(sizeof(Node));p->data = 1;p->next = p;//构建无头结点的循环链表 curr = p; //curr为构建链表时的当前节点 for(i=1;i<n;i++) {P_Node newNode = (P_Node)malloc(sizeof(Node)); newNode->data = i+1;//尾插法 newNode->next = curr->next;curr->next = newNode;curr  = newNode; }while(--k)r = p,p = p->next;//将指针p移动到k位置。p为循环链表创建时的第一个节点 while(n--){//对n个数依次进行判断 for(i=m-1;i--;r=p,p=p->next);//将指针r移动到m-1位置上准备删除。循环结束时指针p指向m位置上 r->next = p->next;//删除m位置上的节点printf("%d->",p->data);free(p);p = r->next;//指针p移动到m+1位置上的节点上,开始新一轮的判断 } }  int main(){josephusRing(9,5,1); printf("\n\n哈哈哈!约瑟夫环!\n");return 0;}



0 0