自己总结一些会常用到的C语言知识点,复习够用,总结的不好,请多提意见,互相学习进步


关于算法 

转载自:

https://blog.csdn.net/qq_32353771/article/details/54585798

https://blog.csdn.net/wangiijing/article/details/51485119  


/***********************************************************二级指针****************************************************************/



//二级指针学习


#include <stdio.h>//输入输出头文件。
#include <stdlib.h>//本程序需要用到malloc/free函数,引用该头文件。
int main()
{
    int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; //定义二维数组a,并赋值从1-12.
    int ** p = NULL;//定义二维指针。
    int i, j;
     
    p = (int **)malloc(sizeof(int *) *3);//要访问的数组有三行,所以申请三个一维指针变量。
    for(i = 0; i < 3; i ++)
    {
        p[i] = a[i];//将二维数组行地址赋值到对应的一维指针上。
    }
     
    for(i = 0; i < 3; i ++)
    {
        for(j = 0; j < 4; j ++)
            printf("%d ", p[i][j]); //用指针输出元素。p[i][j]这里也可以写作*(*(p+i) + j)。
        printf("\n"); //每行输出后加一个换行
    }
     
    free(p);//释放申请的内存。
     
    return 0;
}
/************************************************************指针函数****************************************************************/
//指针函数学习
//指针函数 本质是函数 ,返回一个地址
//类型说明符 *(函数名)(参数)
//-->float *fun();
//float *p;
//p = fun(a);


#include<iostream>
using namespace std;


int *add(int a,int b)
{
int c = a+b;
return &c;
}
int *sub(int a,int b)
{
int c = a-b;
return &c;
}
int main()
{
char *s = "ad sf";
int a =3,b =2;
int *p = add(a,b);
int *p1 = sub(a,b);
char *p2 = ss(s);
cout<<"add:"<<*p<<endl;
cout<<"sub:"<<*p1<<endl;
return 0;
}
/*********************************************************函数指针*******************************************************************/


//函数指针学习
//函数指针 指向函数的指针变量  本质是一个指针变量
//类型说明符 (*函数名)(参数)  
//-->int (*f) (int x); 声明一个函数指针
//f=func;  将func函数的首地址赋给指针f 


/*
直接定义函数指针作为返回参数
int (*fuc2(int))(int,int);//显示定义 
总结:fuc2是一个函数,形参为(int),返回一个指向int(int,int)的函数指针。
*/


#include<iostream>


using namespace std;


typedef int (*Fun)(int ,int);
Fun fun;//此时 ,为指向某种类型函数的函数指针类型,而不是具体指针 ,用它可以定义具体指针
int add(),sun();


int add(int a,int b)
{
return a+b;
}
 
 int sub(int a,int b)
{
return a-b;
}
int fun1(int (*f)(int,int),int a,int b)//函数指针做形参
{
int ret = add(a,b);
return ret;
}
int main()
{
int a =4, b =4;
int ret = fun1(fun,a,b);
cout<<ret<<endl;




fun = add;
int c = (*fun)(2,3);
cout<<"add:"<<c<<endl;


fun = sub;
int c1 = (*fun)(3,2);
cout<<"sub:"<<c1<<endl;
return 0;
}
 
include<stdio.h>
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}

int fun(int (*p)(int,int),int a,int b)//p=max  a=6 b=8    1.函数调用时定义  2.实参传递给形参时赋值  3.函数体中调用
{
int ret = (*p)(a,b);
return ret;
}
int main()
{
int ret;
ret = fun(max,6,8);
printf("ret:%d\n",ret);

ret = fun(min,6,8);
printf("ret:%d\n",ret);
}
/***************************************************函数指针数组*********************************************************************/
#include<stdio.h>


void add(int a,int b)
{
printf("result:%d\n",a+b);
}
void sub(int a,int b)
{
printf("result:%d\n",a-b);
}
void mul(int a,int b)
{
printf("result:%d\n",a*b);
}
void my_div(int a,int b)
{
if(b==0)
{
puts("cant't be zero");
}
else
{
printf("result:%d\n",a/b);
}
}


int main()
{
int a,b,choose;
void (*p[4])(int,int)={add,sub,mul,my_div};

int i;
for(;;)
{
puts("please input your choose:1 add 2 sub  3 mul 4 div");
scanf("%d",&choose);
puts("input two oprator:");
scanf("%d%d",&a,&b);
p[choose-1](a,b);
}
}
/***************************************************函数指针做形参*********************************************************************/


#include<stdio.h>


void add(int a,int b)
{
printf("result:%d\n",a+b);
}
void sub(int a,int b)
{
printf("result:%d\n",a-b);
}
void mul(int a,int b)
{
printf("result:%d\n",a*b);
}
void my_div(int a,int b)
{
if(b==0)
{
puts("cant't be zero");
}
else
{
printf("result:%d\n",a/b);
}
}


void fun(void (*pf)(int,int),int a,int b)
{
(*pf)(a,b);
}

int main()
{

void (*pf)(int,int)=NULL;
char choose;
int a,b;
puts("input your choose: 1.+ 2.- 3.* 4./ ");
scanf("%c",&choose);

puts("please input two integer:");
scanf("%d%d",&a,&b);
switch(choose)
{
case '+':
fun(add,a,b);
break;
case '-':
fun(sub,a,b);
break;
case '*':
fun(mul,a,b);
break;
case '/':
fun(my_div,a,b);
break;

default:
puts("choose error");
break;

}
return 0; 


}
/***************************************************C++函数重载和重写*********************************************************************/
#include<iostream>
using namespace std;


class Base {
private:
virtual void display() 

cout<<"父类 display()"<<endl; 
}
void say()
{
cout<<"父类 say()"<<endl;
}
public:
void exec()
{
display();
say(); 
}
void f1(string a) 

cout<<"父类 f1(string)"<<endl;
}
//overload,两个f1函数在Base类的内部被重载
void f1(int a,string aa) 
{
cout<<"父类 重载 f1(int,string)"<<endl; 

};


class DeriveA:public Base{
public:
//override,基类中display为虚函数,故此处为重写  被重写的必须是virtual类型的
void display() 

cout<<"子类重写父类 display()"<<endl; 
}
//redefining,f1函数在Base类中不为虚函数,故此处为重定义
void f1(int a,int b) 

cout<<"子类重定义父类  f1(int,int)"<<endl;
}
//redefining,同上
void say()

cout<<"子类重定义父类 say()"<<endl;

};




int main()
{
int x;
int y;
string aa;
DeriveA a;
Base *b = &a;
b->f1(aa);
b->exec(); //display():version of DeriveA call(polymorphism) //say():version of Base called(allways )
//b里边的函数display被A类覆盖,但是say还是自己的。
a.exec(); //same result as last statement   
a.say();

}
/***************************************************冒泡排序*********************************************************************/
原理:假设n个数据排序   每次两个数进行比较 从数组的前两个元素开始   如果前边的数>后边的数 就交换 
      第一趟会求出一个最大值  并且放到最后边(从小到大)
  然后以此类推  经过n-1趟 就排好了


#include<stdio.h>
int main()
{
int i=0,j=0,tmp=0;   
int a[8]={90,78,95,65,82,97,61,68};


for(i=0;i<7;i++)//排了7趟
{
for(j=0;j<7-i;j++)
{
if(a[j]>a[j+1])
{
tmp  = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
}
}
}


for(i=0;i<8;i++)
{
printf("%d  ",a[i]);
}


}
/***************************************************斐波那契数列*********************************************************************/


输出Fibonacci数列的前20项 先正序输出 然后逆序输出结果 


  1 1 2  3   5  8  13  21 34  55 。。。 


  #include<stdio.h>




int main()
{
int a[20]={1,1};
int i;
for(i=2;i<20;i++)
{
a[i] = a[i-1]+a[i-2];
}

for(i=0;i<20;i++)
{
printf("%d ",a[i]);
}
putchar('\n');

for(i=19;i>=0;i--)
{
printf("%d ",a[i]);
}
}

/***************************************************素数(质数)*********************************************************************/
输出100-199中的全部素数 
素数:除了1和自己 不能被其他任何数整除的数 
数据%比他小的任意一个数!=0  --》素数
#include<stdio.h>
int main()
{
int i,j;

for(i=100;i<=199;i++)
{
//处理;//
for(j=2;j<i;j++)//j==i 说明是素数
{
if(i%j==0)
{
break;//说明此时的i不是素数
}
}
if(i==j)
{
printf("%d  ",i);
}
}

}
/***************************************************杨辉三角*********************************************************************/
输出杨辉三角型 输出10阶就可以 


1 0 0 0 0 0 0  
1 1 0 0 0 0 0 
1 2 1 0 0 0 0 
1 3 3 1 0 0 0 
1 4 6 4 1 0 0
1 5 10 10 5 1 0


#include<stdio.h>


int  main()
{
int a[10][10] = {{1},{1},{1},{1},{1},{1},{1},{1},{1},{1}};


int i,j;
for(i=1;i<10;i++)
{
for(j=1;j<10;j++)
{
a[i][j] = a[i-1][j]+a[i-1][j-1];
}
}


for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
if(j<=i)
{
printf("%3d ",a[i][j]);
}
}
putchar('\n');
}
}
/***************************************************鞍点*********************************************************************/
判断数组中是否存在鞍点 (在该行最大 在该列最小)


1  2   6   4 
    5  6   7   8
    9  10  11  12


    6就是鞍点


#include<stdio.h>


int  main()
{
int a[3][4]={{1,2,6,4},{5,6,7,8},{9,10,11,12}};
int max = 0,min;
int i,j,k,line;
for(i=0;i<3;i++)
{

for(j=0;j<4;j++)
{
//找到行的最大值并用line记录其列的下标
if(max<a[i][j])
{
max = a[i][j];
line = j;//line 最大值所在的列
}
}

min = a[0][line];
for(k=1;k<3;k++)
{
//找列数为line的最小值
if(a[k][line]<min)
{
min = a[k][line];

}
}

if(max==min)
{
printf("鞍点:%d %d\n",i,line);
}
max = 0;
}
}
/***************************************************随机数*********************************************************************/
中国福彩35选7 
  随机生成1-35内不重复的7个数字 然后让用户自己输入一组号码 
中奖规则:
猜中:
7个500万 
6个100万
5个1万
4个5000 
3个500 
0,1,2 没中奖

6 3 1 8 4 9 12 
1 3 13 8 4 7 9

#include<stdio.h>


int main()
{
int num[7]={0};//保存随机数
int a[7]={0};
int count=0,i,j;
srand(time(0));


for(i=0;i<7;i++)// 生成7个随机数
{
num[i] = rand()%35+1;//产生随机数
for(j=0;j<i;j++)//保证随机数不重复
{
if(num[i]==num[j])//如果新产生的数与之前的重复 就在这个位置上重新出一个数
{
i--;
break;
}
}
}

puts("please input 7 numbers:");
for(i=0;i<7;i++)
{
scanf("%d",&a[i]);
}



for(i=0;i<7;i++)//用户输入
{
for(j=0;j<7;j++)//随机数
{
if(num[j]==a[i])
{
count++;
break;
}
}
}


switch(count)
{
case 7:
puts("五百万!!");
break;
case 6:
puts("一百万!!");
break;
case 5:
puts("一万!!");
break;
case 4:
puts("五千!!");
break;
case 3:
puts("五百!!");
break;
default:
puts("come on!");
break;
}

}


/************************************************线程读者与写者问题****************************************************************/


//读者与写者问题
#include <stdio.h>
#include <process.h>
#include <windows.h>
//设置控制台输出颜色
BOOL SetConsoleColor(WORD wAttributes)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
return FALSE;

return SetConsoleTextAttribute(hConsole, wAttributes);
}
const int READER_NUM = 5;  //读者个数
//关键段和事件
CRITICAL_SECTION g_cs, g_cs_writer_count;
HANDLE g_hEventWriter, g_hEventNoReader;
int g_nReaderCount;
//读者线程输出函数(变参函数的实现)
void ReaderPrintf(char *pszFormat, ...)
{
va_list   pArgList;

va_start(pArgList, pszFormat);
EnterCriticalSection(&g_cs);
vfprintf(stdout, pszFormat, pArgList);
LeaveCriticalSection(&g_cs);
va_end(pArgList);
}
//读者线程函数
unsigned int __stdcall ReaderThreadFun(PVOID pM)
{
ReaderPrintf("     编号为%d的读者进入等待中...\n", GetCurrentThreadId());
//等待写者完成
WaitForSingleObject(g_hEventWriter, INFINITE);
 
//读者个数增加
EnterCriticalSection(&g_cs_writer_count);
g_nReaderCount++;
if (g_nReaderCount == 1)
ResetEvent(g_hEventNoReader);
LeaveCriticalSection(&g_cs_writer_count);
 
//读取文件
ReaderPrintf("编号为%d的读者开始读取文件...\n", GetCurrentThreadId());
 
Sleep(rand() % 100);
 
//结束阅读,读者个数减小,空位增加
ReaderPrintf(" 编号为%d的读者结束读取文件\n", GetCurrentThreadId());
 
//读者个数减少
EnterCriticalSection(&g_cs_writer_count);
g_nReaderCount--;
if (g_nReaderCount == 0)
SetEvent(g_hEventNoReader);
LeaveCriticalSection(&g_cs_writer_count);
 
return 0;
}
//写者线程输出函数
void WriterPrintf(char *pszStr)
{
EnterCriticalSection(&g_cs);
SetConsoleColor(FOREGROUND_GREEN);
printf("     %s\n", pszStr);
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
LeaveCriticalSection(&g_cs);
}
//写者线程函数
unsigned int __stdcall WriterThreadFun(PVOID pM)
{
WriterPrintf("写者线程进入等待中...");
//等待读文件的读者为零
WaitForSingleObject(g_hEventNoReader, INFINITE);
//标记写者正在写文件
ResetEvent(g_hEventWriter);

//写文件
WriterPrintf("  写者开始写文件.....");
Sleep(rand() % 100);
WriterPrintf("  写者结束写文件");
 
//标记写者结束写文件
SetEvent(g_hEventWriter);
return 0;
}
int main()
{
printf("  读者写者问题\n");
printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
 
//初始化事件和信号量
InitializeCriticalSection(&g_cs);
InitializeCriticalSection(&g_cs_writer_count);
 
//手动置位,初始已触发
g_hEventWriter = CreateEvent(NULL, TRUE, TRUE, NULL);
g_hEventNoReader  = CreateEvent(NULL, FALSE, TRUE, NULL);
g_nReaderCount = 0;
 
int i;
HANDLE hThread[READER_NUM + 1];
//先启动二个读者线程
for (i = 1; i <= 2; i++)
hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
//启动写者线程
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL);
Sleep(50);
//最后启动其它读者结程
for ( ; i <= READER_NUM; i++)
hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
WaitForMultipleObjects(READER_NUM + 1, hThread, TRUE, INFINITE);
for (i = 0; i < READER_NUM + 1; i++)
CloseHandle(hThread[i]);
 
//销毁事件和信号量
CloseHandle(g_hEventWriter);
CloseHandle(g_hEventNoReader);
DeleteCriticalSection(&g_cs);
DeleteCriticalSection(&g_cs_writer_count);
return 0;
}




/**************************************************获取物理屏幕大小******************************************************************/


#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <windows.h>
int main()
{
printf("    获取屏幕大小 物理大小\n");        
printf(" -- By MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");   

int nScreenWidth, nScreenHeight;
HDC hdcScreen = GetDC(NULL);   //获取屏幕的HDC
nScreenWidth = GetDeviceCaps(hdcScreen, HORZSIZE);
nScreenHeight = GetDeviceCaps(hdcScreen, VERTSIZE);

printf("屏幕大小(毫米) 宽:%d 高:%d\n", nScreenWidth, nScreenHeight);
printf("    下面将屏幕大小由毫米换算到英寸\n");
const double MILLIMETRE_TO_INCH = 0.03937;
double aa = nScreenHeight * nScreenHeight + nScreenWidth * nScreenWidth;
double fDiagonalLen = sqrt(aa);

printf("屏幕对角线长为:%.2lf毫米 约 %.2lf英寸\n", fDiagonalLen, fDiagonalLen * MILLIMETRE_TO_INCH);
getch();
return 0;
}


/*************************************************线程回调***********************************************************************/


//回调函数
#include <iostream>
#include <thread>
#include <mutex>
 
using namespace std;
 
mutex mtx;
 
class Test {
private:
    int a;
    int b;
public:
    Test(int a, int b) : a(a), b(b) {}
 
    void fun1() {
        lock_guard<mutex> lck(mtx);
        cout << a + b << endl;
    }
     
    void fun2() {
        lock_guard<mutex> lck(mtx);
        cout << a - b << endl;
    }
};
 
int main() {
    Test test(10, 3);
 
    auto f1 = bind(&Test::fun1, test);
    auto f2 = bind(&Test::fun2, test);
 
    thread t1(f1);
    thread t2(f2);
thread t;
    t1.join();
    t2.join();
 
    return 0;
}


/***************************************************字符串数字互转*********************************************************************/




//数组方法 atoi()
#include<stdio.h>
#include<string.h>
int main()
{
int i;
char str[]="123";
int b=0;//保存每位数 
int c=0;//十进制数
for(i=0;i<strlen(str);i++)
{
b = str[i]-'0';
c = c*10+b;//1*10+2   12*10+3  
 
}
printf("result:%d\n",c);
}


Function:为四舍五入的输出格式,对数字与字符串之间的相互转换的操作和输出数据
#include<stdio.h>
#include<iostream>
#include<time.h>
using namespace std;
typedef long long LL;




string 去除末尾零(string val1)
{  
const char *p=val1.data();
int ii=val1.length();
for (int i = val1.length()-1; i > 0; i--)
{  
if (p[i]!=48)
{  
ii=i;
goto LN1; 
}
 }
LN1:;  
return val1.replace(ii+1,val1.length(),"");
 }




string NumToString(double num,int pre)//数字转字符串,使用sprintf(char数组名,类型,数字变量名) 
{  
char str1[10]={0};
char str2[10]={0};
sprintf(str1,"%%.%dlf",pre); //将精度设为可变参数
sprintf(str2,str1,num);
//去除末尾零(str2);
return str2;     //返回最后(字符串)结果




//char str[10]="";
//sprintf(str,"%.0lf",num);
//return str;
}


double StringToNum(char *str1,int pre)//字符串转数字,使用sscanf()函数
{
double num;
//sscanf(str1,"%lf",&num);//double 形式输出
sscanf(str1,"%le",&num);//科学计数法形式输出
NumToString(num,pre);
//round(num,2);
return num;
}
int main()
{
clock_t start,finish;
double totaltime;
    start=clock();


//NumToString(123.9999999);
//StringToNum("12.1432E-2");


int pre = 0;  //pre为可变精度  为变量



StringToNum("12E8",pre); // 参数1 为要处理的数据 参数2 为输出精度

cout<<"Done!"<<endl;
finish=clock();
    totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
    cout<<"\n此程序的运行时间为"<<totaltime<<"秒!"<<endl;
}


/*****************************************************递归1-100和*******************************************************************/


#include<stdio.h>


int get_sum(int num)
{
int result;
if(num==1)
{
return 1;
}
result = get_sum(num-1) + num;
return result;
}
int main()
{
printf("%d\n",get_sum(100));
return 0;
}


/*****************************************************strcmp*******************************************************************/
#include<stdio.h>


int fun(char *p,char *q)
{

while((*p&&*q)&&(*p==*q))
{
p++;
q++;
}
if(*p>*q)
{
return 1;
}
if(*p<*q)
{
return -1;
}
else
{
return 0;
}
}
int main()
{
int ret;
char str1[] = "acde";
char str2[] = "abce";
ret = fun(str1,str2);
printf("%d\n",ret);
return 0;
}
/*****************************************************strcpy*******************************************************************/
#include<stdio.h>
void fun(char *p,char *q)
{
while(*q)
{
*p = *q;
p++;
q++;
}
*p='\0';
}
int main()
{
char str1[100] = "hello";
char str2[]="songjian";
fun(str1,str2);
printf("%s\n",str1);
return 0;
}
/*****************************************************strcat*******************************************************************/
include<stdio.h>


void fun(char *p,char *q)
{
int i=0,j=0;
while(p[i]!='\0')
{
i++;
}
for(j = 0;q[j]!='\0';j++)
{
p[i] = q[j];
i++;
}
p[i]='\0';
}


int main()
{
char str1[] = "song";
char str2[] = "jian";
fun(str1,str2);
printf("%s\n",str1);
return 0;
}
/*****************************************************strlen*******************************************************************/
#include<stdio.h>


int fun(char *str)
{
int i = 0;
while(str[i]!='\0')
{
i++;
}
return i;
}
int main()
{
int len = 0;
char str[100]={'\0'};
puts("please input a string:");
scanf("%s",str);
len = fun(str);
printf("%d\n",len);
return 0;
}
/****************************************************水仙花数*******************************************************************/
#include<stdio.h>


int main()
{
int n;
int g,s,b;
for(n=100;n<1000;n++)
{
b = n/100;
s = n/10%10;
g = n %10;
if(n==g*g*g+s*s*s+b*b*b)
{
printf("%d ",n);
}
}
printf("\n");
return 0;
}
/******************************************************各种算法排序效率对比******************************************************************/
https://blog.csdn.net/qq_32353771/article/details/54585798
https://blog.csdn.net/wangiijing/article/details/51485119  
/********************************************************二叉树遍历****************************************************************/
#include<stdio.h>


typedef struct node_t
{
char data;//数据域
struct node_t *lchild;//指向左子节点的指针
struct node_t *rchild;//指向右子节点的指针
}tree_node_t;


//先序遍历  根 左 右
void first_order(tree_node_t *r)
{
if(r != NULL)
{
printf("%c ",r->data);
first_order(r->lchild);
first_order(r->rchild);
}
}
//中序遍历 左 根 右
void middle_order(tree_node_t *r)
{
if(r != NULL)
{
middle_order(r->lchild);
printf("%c ",r->data);
middle_order(r->rchild);
}
}
//后序遍历 左 右 根
void last_order(tree_node_t *r)
{
if(r != NULL)
{
last_order(r->lchild);
last_order(r->rchild);
printf("%c ",r->data);
}
}
int main()
{
tree_node_t A = {'A',NULL,NULL};
tree_node_t B = {'B',NULL,NULL};
tree_node_t C = {'C',NULL,NULL};
tree_node_t D = {'D',NULL,NULL};
tree_node_t E = {'E',NULL,NULL};
tree_node_t F = {'F',NULL,NULL};


A.lchild = &B;
A.rchild = &C;
B.lchild = &D;
B.rchild = &E;
C.lchild = &F;

first_order(&A);
printf("\n");
middle_order(&A);
printf("\n");
last_order(&A);
printf("\n");


return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct _TREE_NODE
{
int data;
struct _TREE_NODE* parent;
struct _TREE_NODE* left_child;
struct _TREE_NODE* right_child;
}TREE_NODE;
/*
根据上面的数据结构,
我们看到每一个数据节点都有三个指针,
分别是:指向父母的指针,
指向左孩子的指针,
指向右孩子的指针。
每一个节点都是通过指针相互连接的。
相连指针的关系都是父子关系。
那么排序二叉树又是什么意思呢?
其实很简单,只要在二叉树的基本定义上增加两个基本条件就可以了:
(1)所有左子树的节点数值都小于此节点的数值;
(2)所有右节点的数值都大于此节点的数值。
*/
//1.创建二叉树节点
TREE_NODE* create_tree_node(int data)
{
TREE_NODE* pTreeNode = NULL;
pTreeNode = (TREE_NODE*)malloc(sizeof(TREE_NODE));
assert(NULL != pTreeNode);
memset(pTreeNode,0,sizeof(TREE_NODE));
pTreeNode->data = data;
return pTreeNode;
}
/*
分析:我们看到,二叉树节点的创建和我们看到的链表节点、堆栈节点创建没有什么本质的区别。
首先需要为节点创建内存,然后对内存进行初始化处理。
最后将输入参数data输入到tree_node当中即可。
*/
//2.数据的查找
TREE_NODE* find_data_in_tree_node(const TREE_NODE* pTreeNode,int data)
{
if(NULL == pTreeNode)
{
return NULL;
}
if(data == pTreeNode->data)
return (TREE_NODE*)pTreeNode;
else if(data < pTreeNode->data)
return find_data_in_tree_node(pTreeNode->left_child,data);
else
return find_data_in_tree_node(pTreeNode->right_child,data);
}
/*
分析:我们的查找是按照递归迭代进行的。
因为整个二叉树是一个排序二叉树,
所以我们的数据只需要和每一个节点依次比较就可以了,
如果数值比节点数据小,那么向左继续遍历;
反之向右继续遍历。
如果遍历下去遇到了NULL指针,只能说明当前的数据在二叉树中还不存在。
*/
//3.数据统计
int count_node_number_in_tree(const TREE_NODE* pTreeNode)
{
if(NULL == pTreeNode)
return 0;
return 1+count_node_number_in_tree(pTreeNode->left_child)
+ count_node_number_in_tree(pTreeNode->right_child);
}
/*
分析:和上面查找数据一样,统计的工作也比较简单。
如果是节点指针,那么直接返回0即可,
否则就需要分别统计左节点树的节点个数、右节点树的节点个数,
这样所有的节点总数加起来就可以了。
*/
//4.按照从小到大的顺序打印节点的数据
void print_all_node_data(const TREE_NODE* pTreeNode)
{
if(pTreeNode)
{
print_all_node_data(pTreeNode->left_child);
printf("%d\n",pTreeNode->right_child);
print_all_node_data(pTreeNode->right_child);
}
}
/*
分析:因为二叉树本身的特殊性,
按顺序打印二叉树的函数本身也比较简单。
首先打印左子树的节点,
然后打印本节点的数值,
最后打印右子树节点的数值,
这样所有节点的数值就都可以打印出来了。
*/
//5.统计树的高度
int calculate_height_of_tree(const TREE_NODE* pTreeNode)
{
int left,right;
if(NULL == pTreeNode)
return 0;
left = calculate_height_of_tree(pTreeNode->left_child);
right = calculate_height_of_tree(pTreeNode->right_child);
return (left > right) ? (left + 1) : (right + 1);
}
/*
分析:树的高度其实是指所有叶子节点中,
从根节点到叶子节点的最大高度可以达到多少
。当然,程序中表示得已经很明白了,
如果节点为空,那么很遗憾,节点的高度为0;
反之如果左子树的高度大于右子树的高度,
那么整个二叉树的节点高度就是左子树的高度加上1;
如果右子树的高度大于左子树的高度
,那么整个二叉树的高度就是右子树的高度加上1。
计算树的高度在我们设计平衡二叉树的时候非常有用,
特别是测试的时候
*/
int main()
{

}


/************************************************************************************************************************/
/************************************************************************************************************************/
/************************************************************************************************************************/
/************************************************************************************************************************/
/************************************************************************************************************************/
/************************************************************************************************************************/


猜你喜欢

转载自blog.csdn.net/idijsj/article/details/80951705
今日推荐