關於手寫代碼

        在面試的過程中,軟件主管爲了考察面試者的代碼水平,往往讓面試者手寫一段經典代碼,比如字符串拷貝函數strcpy()、冒泡排序、二叉樹的三種遍歷(先序、中序、後序)等。這就需要面試者在複習的過程中理清算法的原理、畫算法流程圖或者UML類圖、會寫僞代碼哪怕是中文也行。
        下面介紹常見的幾種手寫代碼:

  1. 字符串拷貝函數strcpy()
//字符串複製,從src拷貝到dst
char* strcpy(char *dst, const char* src) {
	assert(dst != NULL && src != NULL );

	char *ret = dst;
	while ((*dst++ = *src++) != '\0');
	return ret;
}
  1. 冒泡排序
#include <stdlib.h>
#include <iostream>
using namespace std;
template<typename T>
//整數或浮點數皆可使用
void bubble_sort(T arr[], int len)
{
	int i, j; T temp;
	for (i = 0; i < len - 1; i++)
		for (j = 0; j < len - 1 - i; j++)
			if (arr[j] > arr[j + 1]) {
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
}
int _tmain(int argc, _TCHAR* argv[])
{
	int arr[] = { 61, 17, 29, 22, 34, 60, 72, 21, 50, 1, 62 };
	int len = (int) sizeof(arr) / sizeof(*arr);
	bubble_sort(arr, len);
	for (int i = 0; i < len; i++)
		cout << arr[i] << ' ';
	cout << endl;
	float arrf[] = { 17.5, 19.1, 0.6, 1.9, 10.5, 12.4, 3.8, 19.7, 1.5, 25.4, 28.6, 4.4, 23.8, 5.4 };
	len = (int) sizeof(arrf) / sizeof(*arrf);
	bubble_sort(arrf, len);
	for (int i = 0; i < len; i++)
		cout << arrf[i] << ' ';

	cout << endl;
	system("pause");
	return 0;
}
  1. 二叉樹的先序、中序、後序遍歷,遞歸方式實現
typedef char ElemType;
typedef struct btnode
{
	ElemType data;
	struct btnode* lchild;
	struct btnode* rchild;
}BTNode;

//先序遍歷(根-->左子樹 -->右子樹)
void PreOrder(BTNode *b)
{
	if (b != NULL)
	{
		printf("%c ", b->data); //訪問根結點
		PreOrder(b->lchild);
		PreOrder(b->rchild);
	}
}

//中序遍歷(左子樹 --> 根 -->右子樹)
void InOrder(BTNode *b)
{
	if (b != NULL)
	{
		InOrder(b->lchild);
		printf("%c ", b->data); //訪問根結點
		InOrder(b->rchild);
	}
}

//後序遍歷(左子樹 -->右子樹 --> 根)
void PostOrder(BTNode *b)
{
	if (b != NULL)
	{
		InOrder(b->lchild);
		InOrder(b->rchild);
		printf("%c ", b->data); //訪問根結點
	}
}

  1. 二叉樹的先序、中序、後序遍歷,非遞歸方式實現
//-------------- 非遞歸實現
//先序遍歷的非遞歸方法:由先序遍歷的過程可知,先訪問根結點,再訪問左子樹,最後訪問右子樹。
//因此,先將根結點進棧,在棧不空時循環: 出棧p,訪問*p結點,將其右孩子進棧,再將左孩子結點進棧。
//算法如下:
void PreOrder1(BTNode *b)
{
	BTNode *St[100], *p;
	int top = -1;
	if (b != NULL)
	{
		top++;        //根結點入棧
		St[top] = b; 
		while (top > -1)      //棧不爲空時循環
		{
			p = St[top];      //進棧並訪問該結點
			top--;
			printf("%c ", p->data);

			if (p->rchild != NULL)   //右孩子結點入棧
			{
				top++;
				St[top] = p->rchild;
			}

			if (p->lchild != NULL)   //左孩子結點入棧
			{
				top++;
				St[top] = p->lchild;
			}
		}
		printf("\n");

	}
}

//中序遍歷的非遞歸方法:由中序遍歷的過程可知,採用一個棧保存需要返回的結點指針,先掃描(並非訪問)根結點的
//所有左結點並將它們一一入棧。然後,出棧一個結點,顯然該結點沒有左孩子結點或者右孩子結點已訪問過,則訪問它。
//接着,掃描該結點的右孩子結點,將其進棧,再掃描該右孩子結點的所有左結點並一一入棧,如此這樣,直到棧空爲止。
//算法如下:
void InOrder1(BTNode *b)
{
	BTNode *St[100], *p;
	int top = -1;
	if (b != NULL)
	{
		p = b;
		while (top > -1 || p != NULL)
		{
			while (p != NULL)     //掃描*p的所有左結點併入棧
			{
				top++;
				St[top] = p;
				p = p->lchild;
			}

			if (top > -1)
			{
				p = St[top];            //出棧*p的結點
				top--;
				printf("%c ", p->data); //訪問之
				p = p->rchild;          //掃描*p的右孩子結點
			}
		}
		printf("\n");
	}
}

//後序遍歷的非遞歸方法:由後序遍歷的過程可知,採用一個棧保存需要返回的結點指針,先掃描根結點的
//所有左結點並將它們一一入棧,出棧一個結點*b即當前結點,然後掃描該結點的右孩子結點併入棧,再掃描
//該右孩子結點的所有左結點併入棧。當一個結點的左、右孩子結點均被訪問後再訪問該結點,如此這樣,
//直到棧空爲止。
//    其中的難點是如何判斷一個結點*b的右孩子已訪問過,爲此需要用p保存剛剛訪問過的結點(初值爲NULL),
//若b->rchild = p成立(在後序遍歷中,*b的右孩子結點一定剛好在*b之前訪問),說明*b的左、右子樹均已訪問,
//現在應訪問*b.
//    從上面的過程可知,棧中保存的是當前結點*b的所有祖先結點(均未訪問過)。
//算法如下:
void PostOrder1(BTNode *b)
{
	BTNode *St[100], *p;
	int flag, top = -1;               //棧指針置初值
	if (b != NULL)
	{
		do 
		{
			while (b != NULL)        //將*b的所有左結點進棧
			{
				top++;
				St[top] = b;
				b = b->lchild;
			}

			p = NULL;                  //p指向棧結點的前一個已訪問的結點
			flag = 1;                  //設置b的訪問標記爲已訪問過
			while (top != -1 && flag)
			{
				b = St[top];           //取出當前的棧頂元素
				if (b->rchild == p)    //右孩子不存在或後孩子已被訪問,則訪問*b
				{
					printf("%c ", b->data); //訪問*b結點
					top--;
					p = b;                  //p指向被訪問的結點
				}
				else
				{
					b = b->rchild;         //b指向右孩子結點
					flag = 0;              //設置未被訪問的標記
				}
			}
		} while (top != -1);
		printf("\n");
	}
}
  1. 求二叉樹的高度
//求二叉樹的高度
int BTNodeDepth(BTNode *b)
{
	int lchildDep = 0, rchildDep = 0;
	if (b == NULL)
		return 0;               //空樹的高度爲0
	else{
		lchildDep = BTNodeDepth(b->lchild);  //左子樹的高度
		rchildDep = BTNodeDepth(b->rchild);  //右子樹的高度
		return (lchildDep > rchildDep) ? (lchildDep + 1) : (rchildDep + 1); //取最大值再加1即可
	}
}

發佈了524 篇原創文章 · 獲贊 798 · 訪問量 208萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章