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,9
init(L1);//初始化
type = 0;
createTail(L1,n,type);
printf("L1:");
print(L1);
//L2
init(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);
}
}
//findPath
void 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(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;
}
//检查数组是否合法
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; //此处用位移操作代替/2
int 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;
}
//partition
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;
}
//快速排序
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 8
void 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^b
void 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;
}