首页
社区
课程
招聘
[原创]“美丽的代码”自主命题--利用硬件栈实现树的遍历
发表于: 2008-10-1 12:02 6454

[原创]“美丽的代码”自主命题--利用硬件栈实现树的遍历

2008-10-1 12:02
6454
前一段时间写的东西,不知道合不合题...
相信这个程序的效率一定很高,代码也很简洁,哈哈
不管怎么样,show一个(好像没有说不让用汇编, )
还有,俺很喜欢书,希望能得到一本,哈哈

winxp,vs2008编译通过,其他x86编译平台也是可以的.

// stack_traversal2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

/***********************************************************************************/
[COLOR="Red"]//这部分很混乱,还是参考源代码吧--sigh...[/COLOR]
//┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
//┃功能:利用IA-32硬件的栈结构实现树的遍历			         ┃
//┃							             ┃
//┃1、元素内容(一个简单的结构体STU)				         ┃
//┃┏━━━━┳━━━━━━━┓				  	             ┃
//┃┃int ID   ┃ char* name  ┃					             ┃
//┃┗━━━━┻━━━━━━━┛					             ┃
//┃							             ┃
//┃2、树节点的结构(STU_NODE)				         ┃
//┃┏━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━┓	             ┃
//┃┃PSTU_NODE child   ┃PSTU_NODE right   ┃PSTU pValue	   ┃	             ┃
//┃┗━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━┛	             ┃
//┃ 采用孩子链的方法,容纳多孩子。				         ┃
//┃								┃
//┃3、								┃
//┃┏━━━┓							┃
//┃┃ stu0 ┣━━┳━━━━━━━━━┳━━━━━━━━━┓			┃
//┃┗━┳━┛      ┃		        ┃		      ┃			┃
//┃┏━┻━┓┏━┻━┓	  ┏━┻━┓               ┏━┻━┓			┃
//┃┃ stu1 ┃┃ stu2 ┣━━┓	  ┃ stu3 ┃	┃ stu4 ┣━━┳━━━━┓	┃
//┃┗━┳━┛┗━┳━┛      ┃	  ┗━┳━┛	┗━┳━┛	     ┃            ┃	┃
//┃┏━┻━┓┏━┻━┓┏━┻━┓┏━┻━┓	┏━┻━┓┏━┻━┓┏━┻━┓	┃
//┃┃ stu5 ┃┃ stu6 ┃┃ stu7 ┃┃ stu8 ┣━━┓	┃ stu9 ┃┃stu10┃┃stu11┃	┃
//┃┗━━━┛┗━━━┛┗━━━┛┗━┳━┛      ┃	┗━━━┛┗━━━┛┗━━━┛	┃
//┃			  ┏━┻━┓┏━┻━┓			┃
//┃			  ┃stu12┃┃stu13┃			┃
//┃			  ┗━━━┛┗━━━┛			┃
//┃栈结构更适合实现中-右-左的遍历顺序,所以最终遍历结果应当是:			┃
//┃0-4-11-10-9-3-8-13-12-2-7-6-1-5					┃
//┃								┃
//┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
/***********************************************************************************/


#include <stdio.h>
#include <windows.h>


//元素内容
typedef struct _STU
{
	int ID;
	char* name;
}STU,*PSTU;


//树形结构的节点定义,采用孩子链的定义形式
typedef struct _STU_NODE
{
	_STU_NODE* child;
	_STU_NODE* right;
	PSTU pValue;
}STU_NODE,*PSTU_NODE;


/***********************************************************************/
//遍历算法
//PSTU_NODE top:	树根
//PVOID pFunc:	遍历到树节点后,调用的函数,
//				必须符合BOOL __stdcall pFun(PSOME_STRUCT pStru)这样的定义
//				其中PSOME_STRUCT任意,可以由调用方规定
//				返回TRUE 表示继续遍历,返回FALSE表示终止遍历
void stack_traversal(PSTU_NODE top, PVOID pFunc)
{
	_asm
	{
		push eax
		push ecx


		//压入0,标志终止
		xor eax,eax
		push eax


		//压入树的头部
		push dword ptr [top]


		next_traversal:
		pop eax //弹出栈中的剩余数据
		test eax,eax
		je traversal_end //退出遍历


		//暂存这个从栈中弹出的目标
		mov ecx,eax


		//压入这个从栈中弹出的目标的第一个孩子
		mov eax,dword ptr [eax]
		test eax,eax
		je no_child //如果没有孩子,跳走
		push eax //压入第一个孩子
		//压入这个从栈中弹出的目标的其余所有孩子
next_right:
		mov eax,dword ptr [eax+4]
		test eax,eax
		je no_right //如果没有右兄弟,跳走
		push eax
		jmp next_right
no_right:
no_child:
		//游历这个从栈中弹出的目标
		mov eax,dword ptr [ecx+8]
		push eax
		call dword ptr [pFunc]
		test eax,eax
		jnz next_traversal//如果遍历函数pFunc返回继续
pop_not_zero:
		pop eax
		test eax,eax
		jnz pop_not_zero
traversal_end:
		pop ecx
		pop eax
	}
}
/***********************************************************************/


/***********************************************************************/
//遍历调用函数
BOOL __stdcall print_stu(PSTU pStu)
{
	printf("%d\t%s\n",pStu->ID,pStu->name);

	/***********************************/
	//如果想要终止遍历,可以使用下面的代码
	//if(pStu->ID==7)
	//{
	//	return FALSE;
	//}
	/***********************************/

	return TRUE;
}
/***********************************************************************/


/***********************************************************************/
//main函数,构造树结构,调用遍历算法
int _tmain(int argc, _TCHAR* argv[])
{
	STU stu[14];


	int i;
	for(i=0;i<14;i++)
	{
		stu[i].ID = i;
	}


	stu[0].name = "stu0";
	stu[1].name = "stu1";
	stu[2].name = "stu2";
	stu[3].name = "stu3";
	stu[4].name = "stu4";
	stu[5].name = "stu5";
	stu[6].name = "stu6";
	stu[7].name = "stu7";
	stu[8].name = "stu8";
	stu[9].name = "stu9";
	stu[10].name = "stu10";
	stu[11].name = "stu11";
	stu[12].name = "stu12";
	stu[13].name = "stu13";


	PSTU_NODE node = new STU_NODE[14];
	for(i=0;i<14;i++)
	{
		node[i].child = 0;
		node[i].right = 0;
		node[i].pValue = &stu[i];
	}


	node[0].child = &node[1];//0-1,2,3,4
	node[1].right = &node[2];
	node[2].right = &node[3];
	node[3].right = &node[4];


	node[1].child = &node[5];//1-5


	node[2].child = &node[6];//2-6,7
	node[6].right = &node[7];


	node[3].child = &node[8];//3-8


	node[4].child = &node[9];//4-9,10,11
	node[9].right = &node[10];
	node[10].right = &node[11];


	node[8].child = &node[12];//8-12,13
	node[12].right = &node[13];


	stack_traversal(&node[0],print_stu);


	delete[] node;


	return 0;
}
/***********************************************************************/


打印输出
0       stu0
4       stu4
11      stu11
10      stu10
9       stu9
3       stu3
8       stu8
13      stu13
12      stu12
2       stu2
7       stu7
6       stu6
1       stu1
5       stu5

stack_traversal2.rar

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
注释部分,很乱,
修改了半天没有效果'
还是参考源代码吧
2008-10-1 12:11
0
游客
登录 | 注册 方可回帖
返回
//