??xml version="1.0" encoding="utf-8" standalone="yes"?> C语言中判断数据类型长度符 也可以对一个函数调用求|其结果是函数q回cd的大,函数q不会被调用Q我们来看一个完整的例子Q?br>char foo() cin.getline()Ҏq箋C用户l端接受字符Qƈ字W存入字W型数组message中,直到输入了(maxcharsQ?/font>1Q个字符Q第maxchars个字W用来存储字W串l尾?/font>NULL字符'\0')或者接受到了回车ؓ止,q终端键入回车键产生一个换?/font>'\n'Q它?/font>cin.getline()认ؓ是行输入l尾?/font>cin.getline()获得的字W?/font>(除了换行W外)被存储到message数组中。在q回之前Q?/font>cin.getlineQ)函数在存储的q些字符后面d一?/font>NULL字符'\0'?/span>
Cin.ignoreQ)Ҏcin.ignore( 5, 'c' ) 的是从输入流Q?span lang=EN-US>cinQ中提取字符Q提取的字符被忽略(ignoreQ,不被使用。每抛弃一个字W,它都要计数和比较字符Q如果计数D?span lang=EN-US>5 Cin.clear用法如果输入发生错误发生Q那么流状态既被标Cؓ错误Q你必须清除q些错误状态,以你的E序能正适当地l运行。要清除错误状态,需使用clear()函数。此函数带一个参敎ͼ它是你将要设为当前状态的标志倹{,只要?/font>ios::goodbit作ؓ实参
while (!s.IsEmpty()) while ((NULL != root) || !s.empty()) l出一个用cd装的字典树代码,厄。。。做ACM的模板用另一个。。应该放在了“ACM模板”文g夹下了。。?/p>
#include
#include
#include
using namespace std;
Q?Q创Z个数l,
v_Arry.pus
v_Arry.pus
v_Arry.pus
v_Arry.pus
v_Arry.pus
v_Arry.pus
v_Arry.pus
v_Arry.pus
v_Arry.pus
v_Arry.pus
v_Arry.pus
Q?Qmake_he
Q?Q此时可以输出查
变成二叉树就是如下:
v_Arry.pop
二叉树如下:
Q?Qv_Arry.
此时输出l果Q?5Q?wbr>10Q?Q?Q?Q?
二叉树如下:
Q?Qsort_he
Q?Qfind ( v_Arry.beg
原文地址Q?a >http://blog.zol.com.cn/1356/article_1355249.html
]]>#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <cmath>
using namespace std;
void CountSort(int a[], int b[],int num,int d) //计数排序
{
int* c = new int[10];
int index;
for (int i=0;i<=9;i++)
c[i]=0;
int size = num;
for (int j=0;j<size;j++)
{
index=a[j]%(int)pow(10.0,d)/(int)pow(10.0,d-1);
c[index]++;
}
//c[i]包含{于i的元素个?/span>
for (i=1;i<=9;i++)
c[i]=c[i]+c[i-1];
//c[i]包含于{于i的元素个?/span>
for (j=size-1;j>=0;j--)
{
index=a[j]%(int)pow(10.0,d)/(int)pow(10.0,d-1);
b[c[index]-1]=a[j];
c[index]--;
}
for (j=0;j<size;j++) //更新一ơ排序后的a数组
{
a[j]=b[j];
}
delete [] c;
}
void RadixSort(int a[],int b[],int d,int num) //基数排序
{
for(int i=1;i<=d;i++)
CountSort(a,b,num,i);
}
void main()
{
int num,d;
cout<<"输入个数及位?/span>"<<endl;
cin>>num>>d;
int* a = new int[num];
int* b = new int[num];
cout<<"排序前:"<<endl;
for(int i=0;i<num;i++)
{
cin>>a[i];
}
RadixSort(a,b,d,num);
cout<<"排序后:"<<endl;
for (int j=0;j<num;j++)
{
cout<<b[j]<<endl;
}
delete [] a;
delete [] b;
}
]]>
用法
?br>
1. 定义Q?br>sizeof是C/C++中的一个操作符QoperatorQ是也,单的说其作用是q回一个对象或者类型所占的内存字节数?br>MSDN上的解释为:
The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t.
其返回值类型ؓsize_tQ在头文件stddef.h中定义。这是一个依赖于~译pȝ的|一般定义ؓ
typedef unsigned int size_t;
世上~译器林林L,但作Z个规范,它们都会保证char、signed char和unsigned
char的sizeofgؓ1Q毕竟char是我们编E能用的最数据类型?br>2. 语法Q?br>sizeof有三U语法Ş式,如下Q?br>1) sizeof( object ); // sizeof( 对象 );
2) sizeof( type_name ); // sizeof( cd );
3) sizeof object; // sizeof 对象;
所以,
int i;
sizeof( i );
sizeof i;
sizeof( int ); // ok
sizeof int;
既然写法3可以用写?代替Qؓ求Ş式统一以及减少我们大脑的负担,W?U写法,忘掉它吧Q实际上Qsizeof计算对象的大也是{换成对对象类型的计算Q也是_同种cd的不同对象其sizeof值都是一致的。这里,对象可以q一步g伸至表达式,即sizeof可以对一个表辑ּ求|~译器根据表辑ּ的最l结果类型来定大小Q一般不会对表达式进行计。如Q?br>sizeof( 2 );
sizeof( 2 + 3.14 );
{
printf("foo() has been called.\n");
return 'a';
}
int main()
{
size_t sz = sizeof( foo() ); // foo() 的返回值类型ؓcharQ所以sz = sizeof(char )Qfoo()q不会被调用
printf("sizeof( foo() ) = %d\n", sz);
}
C99标准规定Q函数、不能确定类型的表达式以及位域(bit-fieldQ成员不能被计算sizeof|即下面这些写法都是错误的Q?br>sizeof( foo );// error
void foo2() { }
sizeof( foo2() );// error
struct S
{
};
sizeof( S.f1 );// error
3. sizeof的常量?br>sizeof的计发生在~译时刻Q所以它可以被当作常量表辑ּ使用Q如Q?br>char ary[ sizeof( int ) * 10 ]; // ok
最新的C99标准规定sizeof也可以在q行时刻q行计算Q如下面的程序在Dev-C++中可以正执行:
int n;
n = 10; // n动态赋?br>char ary[n]; // C99也支持数l的动态定?br>printf("%d\n", sizeof(ary)); // ok. 输出10
但在没有完全实现C99标准的编译器中就行不通了Q上面的代码在VC6中就通不q编译。所以我们最好还是认为sizeof是在~译期执行的Q这样不会带来错误,让程序的可移植性强些?br>4. 基本数据cd的sizeof
q里的基本数据类型指short、int、long、float、doubleq样的简单内|数据类型,׃它们都是和系l相关的Q所以在不同的系l下取值可能不同,q务必引h们的注意Q尽量不要在q方面给自己E序的移植造成ȝ?br>一般的Q在32位编译环境中Qsizeof(int)的取gؓ4?br>5. 指针变量的sizeof
学过数据l构的你应该知道指针是一个很重要的概念,它记录了另一个对象的地址。既然是来存攑֜址的,那么它当然等于计机内部地址ȝ的宽度。所以在32位计机中,一个指针变量的q回值必定是4Q注意结果是以字节ؓ单位Q,可以预计Q在来?4位系l中指针变量的sizeofl果??br>char* pc = "abc";
int* pi;
string* ps;
char** ppc = &pc;
void (*pf)();// 函数指针
sizeof( pc ); // l果?
sizeof( pi ); // l果?
sizeof( ps ); // l果?
sizeof( ppc ); // l果?
sizeof( pf );// l果?
指针变量的sizeofg指针所指的对象没有M关系Q正是由于所有的指针变量所占内存大相{,所以MFC消息处理函数使用两个参数WPARAM、LPARAMp传递各U复杂的消息l构Q用指向结构体的指针)?br>6. 数组的sizeof
数组的sizeof值等于数l所占用的内存字节数Q如Q?br>char a1[] = "abc";
int a2[3];
sizeof( a1 ); // l果?Q字W?末尾q存在一个NULLl止W?br>sizeof( a2 ); // l果?*4=12Q依赖于intQ?br>一些朋友刚开始时把sizeof当作了求数组元素的个敎ͼ现在Q你应该知道q是不对的,那么应该怎么求数l元素的个数呢EasyQ通常有下面两U写法:
int c1 = sizeof( a1 ) / sizeof( char ); // 总长?单个元素的长?br>int c2 = sizeof( a1 ) / sizeof( a1[0] ); // 总长?W一个元素的长度
写到q里Q提一问,下面的c3Qc4值应该是多少?br>void foo3(char a3[3])
{
int c3 = sizeof( a3 ); // c3 ==
}
void foo4(char a4[])
{
int c4 = sizeof( a4 ); // c4 ==
}
也许当你试图回答c4的值时已经意识到c3{错了,是的Qc3!=3。这里函数参数a3已不再是数组cdQ而是蜕变成指针,相当于char* a3Qؓ什么仔l想惛_不难明白Q我们调用函数foo1ӞE序会在栈上分配一个大ؓ3的数l吗不会Q数l是“传址”的,调用者只需实参的地址传递过去,所以a3自然为指针类型(char*Q,c3的g׃ؓ4?br>7. l构体的sizeof
q是初学者问得最多的一个问题,所以这里有必要多费点笔墨。让我们先看一个结构体Q?br>struct S1
{
char c;
int i;
};
问sizeof(s1){于多少聪明的你开始思考了Qchar?个字节,int?个字节,那么加v来就应该?。是q样吗你在你机器上试q了吗也怽是对的,但很可能你是错的QVC6中按默认讄得到的结果ؓ8?br>WhyZ么受伤的L?br>请不要沮丧,我们来好好琢一下sizeof的定义——sizeof的结果等于对象或者类型所占的内存字节敎ͼ好吧Q那p我们来看看S1的内存分配情况:
S1 s1 = { 'a', 0xFFFFFFFF };
定义上面的变量后Q加上断点,q行E序Q观察s1所在的内存Q你发现了什?br>以我的VC6.0ZQs1的地址?x0012FF78Q其数据内容如下Q?br>0012FF78: 61 CC CC CC FF FF FF FF
发现了什么怎么中间Ҏ?个字节的CC看看MSDN上的说明Q?br>When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.
原来如此Q这是传说中的字节寚w啊!一个重要的话题出现了?br>Z么需要字节对齐计机l成原理教导我们q样有助于加快计机的取数速度Q否则就得多花指令周期了。ؓ此,~译器默认会对结构体q行处理Q实际上其它地方的数据变量也是如此)Q让宽度?的基本数据类型(short{)都位于能?整除的地址上,让宽度ؓ4的基本数据类型(int{)都位于能?整除的地址上,以此cL。这P两个C间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了?br>让我们交换一下S1中char与int的位|:
struct S2
{
int i;
char c;
};
看看sizeof(S2)的结果ؓ多少Q怎么q是8再看看内存,原来成员c后面仍然?个填充字节,q又是ؓ什么啊别着急,下面ȝ规律?br>字节寚w的细节和~译器实现相养I但一般而言Q满三个准则:
1) l构体变量的首地址能够被其最宽基本类型成员的大小所整除Q?br>2) l构体每个成员相对于l构体首地址的偏U量QoffsetQ都是成员大的整数倍,如有需要编译器会在成员之间加上填充字节Qinternal addingQ;
3) l构体的dؓl构体最宽基本类型成员大的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing paddingQ?br>对于上面的准则,有几炚w要说明:
1) 前面不是说结构体成员的地址是其大小的整数倍,怎么又说到偏U量了呢因ؓ有了W?点存在,所以我们就可以只考虑成员的偏U量Q这h考v来简单。想想ؓ什么?br>l构体某个成员相对于l构体首地址的偏U量可以通过宏offsetof()来获得,q个宏也在stddef.h中定义,如下Q?br>
例如Q想要获得S2中c的偏U量Q方法ؓ
size_t pos = offsetof(S2, c);// pos{于4
2) 基本cd是指前面提到的像char、short、int、float、doubleq样的内|数据类型,q里所说的“数据宽度”是指其sizeof的大。由于结构体的成员可以是复合cdQ比如另外一个结构体Q所以在L最宽基本类型成员时Q应当包括复合类型成员的子成员,而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合cd作ؓ整体看待?br>q里叙述h有点拗口Q思考v来也有点挠头Q还是让我们看看例子吧(具体数g以VC6ZQ以后不再说明)Q?br>struct S3
{
char c1;
S1 s;
char c2;
};
S1的最宽简单成员的cd为intQS3在考虑最宽简单类型成员时是将S1“打散”看的Q所以S3的最宽简单类型ؓintQ这P通过S3定义的变量,其存储空间首地址需要被4整除Q整个sizeof(S3)的g应该?整除?br>c1的偏U量?Qs的偏U量呢这时s是一个整体,它作为结构体变量也满_面三个准则,所以其大小?Q偏U量?Qc1与s之间侉K?个填充字节,而c2与s之间׃需要了Q所以c2的偏U量?2Q算上c2的大ؓ13Q?3是不能被4整除的,q样末尾q得补上3个填充字节。最后得到sizeof(S3)的gؓ16?br>通过上面的叙qͼ我们可以得到一个公式:
l构体的大小{于最后一个成员的偏移量加上其大小再加上末填充字节数目Q即Q?br>sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trailing padding )
到这里,朋友们应该对l构体的sizeof有了一个全新的认识Q但不要高兴得太早,有一个媄响sizeof的重要参量还未被提及Q那便是~译器的pack指o。它是用来调整结构体寚w方式的,不同~译器名U和用法略有不同QVC6中通过#pragma pack实现Q也可以直接修改/Zp~译开兟?pragma pack的基本用法ؓQ?pragma pack( n )Qn为字节对齐数Q其取gؓ1????6Q默认是8Q如果这个值比l构体成员的sizeof值小Q那?br>该成员的偏移量应该以此gؓ准,x_l构体成员的偏移量应该取二者的最|
公式如下Q?br>offsetof( item ) = min( n, sizeof( item ) )
再看CZQ?br>#pragma pack(push)
#pragma pack(2) // 必须在结构体定义之前使用
struct S1
{
char c;
int i;
};
struct S3
{
char c1;
S1 s;
char c2;
};
#pragma pack(pop) // 恢复先前的pack讄
计算sizeof(S1)Ӟmin(2, sizeof(i))的gؓ2Q所以i的偏U量?Q加上sizeof(i){于6Q能够被2整除Q所以整个S1的大ؓ6?br>同样Q对于sizeof(S3)Qs的偏U量?Qc2的偏U量?Q加上sizeof(c2){于9Q不能被2整除Q添加一个填充字节,所以sizeof(S3){于10?br>
现在Q朋友们可以L的出一口气了,:)
q有一点要注意Q?#8220;I结构体”Q不含数据成员)的大不?Q而是1。试想一?#8220;不占I间”的变量如何被取地址、两个不同的“I结构体”变量又如何得以区分呢于是Q?#8220;I结构体”变量也得被存储,q样~译器也只能ؓ其分配一个字节的I间用于占位了。如下:
struct S5 { };
sizeof( S5 ); // l果?
8. 含位域结构体的sizeof
前面已经说过Q位域成员不能单独被取sizeof|我们q里要讨论的是含有位域的l构体的sizeofQ只是考虑到其Ҏ性而将其专门列了出来?br>C99规定int、unsigned int和bool可以作ؓ位域cdQ但~译器几乎都Ҏ作了扩展Q允许其它类型类型的存在。用位域的主要目的是压~存储,其大致规则ؓQ?br>1) 如果盔R位域字段的类型相同,且其位宽之和于cd的sizeof大小Q则后面的字D将紧邻前一个字D存储,直到不能容纳为止Q?br>2) 如果盔R位域字段的类型相同,但其位宽之和大于cd的sizeof大小Q则后面的字D将从新的存储单元开始,其偏U量为其cd大小的整数倍;
3) 如果盔R的位域字D늚cd不同Q则各编译器的具体实现有差异QVC6采取不压~方式,Dev-C++采取压羃方式Q?br>4) 如果位域字段之间I插着非位域字D,则不q行压羃Q?br>5) 整个l构体的dؓ最宽基本类型成员大的整数倍?br>q是让我们来看看例子?br>CZ1Q?br>struct BF1
{
char f1 : 3;
char f2 : 4;
char f3 : 5;
};
其内存布局为:
|_f1__|__f2__|_|____f3___|____|
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
0 3 7 8 1316
位域cd为charQ第1个字节仅能容U下f1和f2Q所以f2被压~到W?个字节中Q而f3?br>能从下一个字节开始。因此sizeof(BF1)的结果ؓ2?br>CZ2Q?br>struct BF2
{
char f1 : 3;
short f2 : 4;
char f3 : 5;
};
׃盔R位域cd不同Q在VC6中其sizeof?Q在Dev-C++中ؓ2?br>CZ3Q?br>struct BF3
{
char f1 : 3;
char f2;
char f3 : 5;
};
非位域字D늩插在其中Q不会生压~,在VC6和Dev-C++中得到的大小均ؓ3?br>9. 联合体的sizeof
l构体在内存l织上是序式的Q联合体则是重叠式,各成员共享一D内存,所以整个联合体的sizeof也就是每个成员sizeof的最大倹{结构体的成员也可以是复合类型,q里Q复合类型成员是被作为整体考虑的?br>所以,下面例子中,U的sizeof值等于sizeof(s)?br>union U
{
int i;
char c;
S1 s;
};
转自Q?a >http://blog.sina.com.cn/s/blog_5af743940100ctd9.html
]]>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
void CountSort(int a[], int b[],int k,int num)
{
int* c = new int[k+1];
for (int i=0;i<=k;i++)
c[i]=0;
int size = num;
for (int j=0;j<size;j++)
c[a[j]]++;
//c[i]包含{于i的元素个?/span>
for (i=1;i<=k;i++)
c[i]=c[i]+c[i-1];
//c[i]包含于{于i的元素个?/span>
for (j=size-1;j>=0;j--)
{
b[c[a[j]]-1]=a[j];
c[a[j]]--;
}
delete [] c;
}
void main()
{
int num,max;
cout<<"输入最大整数及输入个数"<<endl;
cin>>max;
cin>>num;
int* a = new int[num];
int* b = new int[num];
cout<<"排序前:"<<endl;
for(int i=0;i<num;i++)
{
cin>>a[i];
if (a[i]>max)
i--;
}
CountSort(a,b,max,num);
cout<<"排序后:"<<endl;
for (int j=0;j<num;j++)
{
cout<<b[j]<<endl;
}
delete [] a;
delete [] b;
}
]]>#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int Partition(int a[],int p,int r)
{
int ran=rand()%(r-p+1)+p; //随即选取卫兵
swap(a[ran],a[r]);
int x=a[r];
int i=p-1;
for (int j=p;j<r;j++)
{
if (a[j]<=x) //于卫兵的D行对?/span>
{
i++;
swap(a[i],a[j]);
}
}
swap(a[i+1],a[r]);
return i+1;
}
void QuickSort(int a[],int p,int r)
{
int q;
if (p<r)
{
q=Partition(a,p,r);
QuickSort(a,p,q-1);
QuickSort(a,q+1,r);
}
}
int BinarySearch(int a[],int min,int max,int x)
{
int mid;
while (min<max)
{
mid=min+(max-min)/2;
if (a[mid]>=x)
max=mid;
else
min=mid+1; //若不加一可能存在无限循环的结?/span>
}
if (a[min]==x)
return min;
else if(a[max]==x)
return max;
else
return -1;
}
void main()
{
int num;
cin>>num;
int* a = new int[num];
cout<<"排序前:"<<endl;
for(int i=0;i<num;i++)
cin>>a[i];
QuickSort(a,0,num-1);
cout<<"排序后:"<<endl;
for (int j=0;j<num;j++)
{
cout<<a[j]<<endl;
}
cout<<"输入要查扄?/span>"<<endl;
int x;
cin>>x;
int result=BinarySearch(a,0,num-1,x);
if (result>=0)
cout<<"目标位置?"<<result+1<<endl;
else
cout<<"目标不在数组?/span>"<<endl;
}
]]>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
template<class T> void Max_Heap(T a[],int i,int size)
{
int r = 2*i + 2;
int l = 2*i + 1;
int largest;
if (l<size && a[l]>=a[i])
{
largest = l;
}
else
largest = i;
if (r<size && a[r] >=a[largest])
{
largest = r;
}
if (largest != i)
{
swap(a[largest],a[i]);
Max_Heap(a,largest,size);
}
}
template<class T> void Build_Max_Heap(T a[],int size)
{
for (int i=size/2;i>=0;i--)
{
Max_Heap(a,i,size);
}
}
template<class T> void HeapSort(T a[],int size)
{
Build_Max_Heap(a,size);
for (int i=size-1;i>=1;i--)
{
swap(a[i],a[0]); //最大数换到数组末尾
//show(a,size);
size--;
Max_Heap(a,0,size);
}
}
template<class T> void show(T a[],int size)
{
cout<<"排序后结果ؓ"<<endl;
for (int i=0;i<size;i++)
{
cout<<a[i]<<endl;
}
}
int main()
{
int num;
cin>>num;
char* input = new char[num];
for (int i=0;i<num;i++)
{
cin>>input[i];
}
// Build_Max_Heap(input,num); //建立最大堆
HeapSort(input,num); //堆排?/span>
show(input,num);
}
]]>
]]>
合ƈq程中的变量Ҏ搞错Q特别不能忽略合q过E中数组边界的改变!Q!
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
void Merge(int a[],int p,int k,int q)
{
int num1=k-p+1;
int num2=q-k;
int i;
int* b1=new int[num1+1];
int* b2=new int[num2+1];
for (i=0;i<num1;i++)
{
b1[i]=a[p+i];
}
b1[i]=9999;
for (i=0;i<num2;i++)
{
b2[i]=a[k+i+1];
}
b2[i]=9999;
int j=0;i=0;
for(int kk=p;kk<=q;kk++) //注意Q!Q?br>
{
if (b1[i]<=b2[j])
a[kk]=b1[i++];
else
a[kk]=b2[j++];
}
delete [] b1;
delete [] b2;
}
void MergeSort(int a[],int p,int q)
{
if (p<q)
{
int k=(p+q)/2;
MergeSort(a,p,k);
MergeSort(a,k+1,q);
Merge(a,p,k,q);
}
}
int main()
{
int n;
scanf("%d",&n);
int* input=new int[n];
for (int i=0;i<n;i++)
{
scanf("%d",&input[i]);
}
MergeSort(input,0,n-1);
for (int i=0;i<n;i++)
{
printf("%d ",input[i]);
}
delete [] input;
}
]]>
]]>
void PreOrderUnrec(Bitree *t)
{
Stack s;
StackInit(s);
Bitree *p=t;
while (p!=NULL || !StackEmpty(s))
{
while (p!=NULL) //遍历左子?br> {
visite(p->data);
push(s,p);
p=p->lchild;
}
if (!StackEmpty(s)) //通过下一ơ@环中的内嵌while实现叛_树遍?br> {
p=pop(s);
p=p->rchild;
}//endif
}//endwhile
}
2.中序遍历非递归法
void InOrderUnrec(Bitree *t)
{
Stack s;
StackInit(s);
Bitree *p=t;
while (p!=NULL || !StackEmpty(s))
{
while (p!=NULL) //遍历左子?br> {
push(s,p);
p=p->lchild;
}
if (!StackEmpty(s))
{
p=pop(s);
visite(p->data); //讉K根结?br> p=p->rchild; //通过下一ơ@环实现右子树遍历
}//endif
}//endwhile
}
3.后序遍历非递归法
typedef enum{L,R} tagtype;
typedef struct
{
Bitree ptr;
tagtype tag;
}stacknode;
typedef struct
{
stacknode Elem[maxsize];
int top;
}SqStack;
void PostOrderUnrec(Bitree t)
{
SqStack s;
stacknode x;
StackInit(s);
p=t;
do
{
while (p!=null) //遍历左子?br> {
x.ptr = p;
x.tag = L; //标记为左子树
push(s,x);
p=p->lchild;
}
while (!StackEmpty(s) && s.Elem[s.top].tag==R)
{
x = pop(s);
p = x.ptr;
visite(p->data); //tag为RQ表C右子树讉K完毕Q故讉K根结?nbsp;
}
if (!StackEmpty(s))
{
s.Elem[s.top].tag =R; //遍历叛_?br> p=s.Elem[s.top].ptr->rchild;
}
}while (!StackEmpty(s));
}//PostOrderUnrec
二。前序最z算?br>void PreOrderUnrec(Bitree *t)
{
Bitree *p;
Stack s;
s.push(t);
{
s.pop(p);
visit(p->data);
if (p->rchild != NULL) s.push(p->rchild);
if (p->lchild != NULL) s.push(p->lchild);
}
}
三。后序算法之?/strong>
void BT_PostOrderNoRec(pTreeT root)
{
stack<treeT *> s;
pTreeT pre=NULL;
{
if (NULL != root)
{
s.push(root);
root = root->left;
}
else
{
root = s.top();
if (root->right!=NULL && pre!=root->right){
root=root->right;
}
else{
root=pre=s.top();
visit(root);
s.pop();
root=NULL;
}
}
}
}
]]>
举个单的例子?/p>
l你100000个长度不过10的单词。对于每一个单词,我们要判断他出没出现q,如果出现了,W一ơ出现第几个位置?br>q题当然可以用hash来,但是我要介绍的是trie树。在某些斚w它的用途更大。比如说对于某一个单词,我要询问它的前缀是否出现q。这样hash׃好搞了,而用trieq是很简单?br>现在回到例子中,如果我们用最ȝҎQ对于每一个单词,我们都要L扑֮前面的单词中是否有它。那么这个算法的复杂度就是O(n^2)。显然对?00000的范围难以接受。现在我们换个思\惟뀂假设我要查询的单词是abcdQ那么在他前面的单词中,以bQcQdQf之类开头的我显然不必考虑。而只要找以a开头的中是否存在abcd可以了。同LQ在以a开头中的单词中Q我们只要考虑以b作ؓW二个字母的……q样一个树的模型就渐渐清晰?#8230;…
假设有bQabcQabdQbcdQabcdQefgQhiiq?个单词,我们构徏的树是q样的?br>
对于每一个节点,从根遍历C的过E就是一个单词,如果q个节点被标CؓU色Q就表示q个单词存在Q否则不存在?br>那么Q对于一个单词,我只要顺着他从跟走到对应的节点Q再看这个节Ҏ否被标记为红色就可以知道它是否出现过了。把q个节点标记为红Ԍq当于插入了这个单词?br>q样一来我们询问和插入可以一起完成,所用时间仅仅ؓ单词长度Q在q一个样例,便是10?br>我们可以看到Qtrie树每一层的节点数是26^iU别的。所以ؓ了节省空间。我们用动态链表,或者用数组来模拟动态。空间的pQ不会超q单词数×单词长度?/p>
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int num_chars = 26;
class Trie
{
public:
Trie():root(NULL)
{};
Trie(Trie& tr);
int search(const char* word, char* entry ) const;
int insert(const char* word, const char* entry);
int remove(const char* word, char* entry);
private:
struct Trie_node
{
char* data;
Trie_node* branch[num_chars];
Trie_node();
}* root;
};
Trie::Trie_node::Trie_node()
{
data = NULL;
for (int i=0; i<num_chars; ++i)
branch[i] = NULL;
}
int Trie::search(const char* word, char* entry ) const
{
int position = 0;
char char_code;
Trie_node *location = root;
while( location!=NULL && *word!=0 )
{
if (*word>='A' && *word<='Z')
char_code = *word-'A';
else if (*word>='a' && *word<='z')
char_code = *word-'a';
else return 0;
location = location->branch[char_code];
position++;
word++;
}
if ( location != NULL && location->data != NULL )
{
strcpy(entry,location->data);
return 1;
}
else return 0;
}
int Trie::insert(const char* word, const char* entry)
{
int result = 1, position = 0;
if ( root == NULL ) root = new Trie_node;
char char_code;
Trie_node *location = root;
while( location!=NULL && *word!=0 )
{
if (*word>='A' && *word<='Z')
char_code = *word-'A';
else if (*word>='a' && *word<='z')
char_code = *word-'a';
else return 0;
if( location->branch[char_code] == NULL )
location->branch[char_code] = new Trie_node;
location = location->branch[char_code];
position++;
word++;
}
if (location->data != NULL)
result = 0;
else
{
location->data = new char[strlen(entry)+1];
strcpy(location->data, entry);
}
return result;
}
int main()
{
Trie t;
char entry[100];
t.insert("aa", "DET");
t.insert("abacus","NOUN");
t.insert("abalone","NOUN");
t.insert("abandon","VERB");
t.insert("abandoned","ADJ");
t.insert("abashed","ADJ");
t.insert("abate","VERB");
t.insert("this", "PRON");
if (t.search("this", entry))
cout<<"'this' was found. pos: "<<entry<<endl;
if (t.search("abate", entry))
cout<<"'abate' is found. pos: "<<entry<<endl;
if (t.search("baby", entry))
cout<<"'baby' is found. pos: "<<entry<<endl;
else
cout<<"'baby' does not exist at all!"<<endl;
if (t.search("aa", entry))
cout<<"'aa was found. pos: "<<entry<<endl;
}
PS:实现Ҏhttp://met.fzu.edu.cn/eduonline/web/web/resources/articleContent.asp?id=346
]]>
E序代码 E序代码
int num[100];
Sample:
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
qsort(num,100,sizeof(num[0]),cmp);
二、对charcd数组排序Q同intcdQ?br>E序代码 E序代码
char word[100];
Sample:
int cmp( const void *a , const void *b )
{
return *(char *)a - *(char*)b;
}
qsort(word,100,sizeof(word[0]),cmp)
三、对doublecd数组排序Q特别要注意Q?br>E序代码 E序代码
double in[100];
int cmp( const void *a , const void *b )
{
return *(double *)a > *(double *)b ? 1 : -1;
} qsort(in,100,sizeof(in[0]),cmp)Q?br>
四、对l构体一U排?
E序代码 E序代码
struct In {
double data;
int other;
}s[100]
//按照data的g到大将l构体排?关于l构体内的排序关键数据data的类型可以很多种Q?br>参考上面的例子?
int cmp( const void *a ,const void *b)
{
return (*(In *)a).data > (*(In *)b).data ? 1 : -1;
}
qsort(s,100,sizeof(s[0]),cmp);
五、对l构体二U排?
E序代码 E序代码
struct In {
int x; int y;
}s[100];
//按照x从小到大排序Q当x相等时按照y从大到小排序
int cmp( const void *a , const void *b )
{
struct In *c = (In *)a;
struct In *d = (In *)b;
if(c->x != d->x) return c->x - d->x;
else return d->y - c->y;
}
qsort(s,100,sizeof(s[0]),cmp);
六、对字符串进行排?
E序代码 E序代码
struct In {
int data; char str[100];
}s[100];
//按照l构体中字符串str的字兔R序排?
int cmp ( const void *a , const void *b )
{
return strcmp( (*(In *)a)->str , (*(In *)b)->str );
}
qsort(s,100,sizeof(s[0]),cmp);
七、计几何中求凸包的cmp
E序代码 E序代码
int cmp(const void *a,const void *b)
//重点cmp函数Q把除了1点外的所有点Q旋转角度排?
{
struct point *c=(point *)a;
struct point *d=(point *)b;
if( calc(*c,*d,p[1]) < 0) return 1;
else if( !calc(*c,*d,p[1])
&& dis(c->x,c->y,p[1].x,p[1].y) < dis(d->x,d->y,p[1].x,p[1].y))
//如果在一条直U上Q则把远的放在前?
return 1; else return -1;
}
PS: 其中的qsort函数包含?lt;stdlib.h>的头文g里,strcmp包含?lt;string.h>的头文g?
]]>
所有球~号?-12Q?br>W一步,?-4h左边Q?-8h双Q?br> 若倾斜Q假讑֏重(左重雷同Q:
W二步[0]Q将2-4U走Q?-8Ud左边Q?-11Ud双Q?br> 若仍倾斜Q则不同的那个ؓ~号1?P
W三步[0][0]Q将1号与2h较,若相{,?号偏重,反之Q?L偏轻Q?br> 若不倾斜Q则不同的那个在~号2-4中,且偏轻;
W三步[0][1]QQ?-4U两球可得结果;
若不倾斜Q则不同的在9-12中:
W二步[1]Q移?-8球,Ud9-11球:
若倾斜Q假讑֏重(左重雷同Q:
W三步[1][0]QQ?-11U两球可得结果;
若不倾斜Q则12L异常Q?br> W三步[1][1]Q将12L与其它Q意球比较可知是轻是重Q?/p>
如:
0050 所求数?104
112 所求数?21