4-6 帶頭結點的鏈式表操作集
code:
List MakeEmpty()
{
List L;
L = (List)malloc(sizeof(struct LNode));
L->Data = NULL;
L->Next = NULL;
return L;
}
Position Find( List L, ElementType X )
{
List p = L;
while(p && p->Data!=X) {
p = p->Next;
}
if(p && X==p->Data) {
return p;
} else {
return ERROR;
}
}
bool Insert( List L, ElementType X, Position P )
{
List r = L;
List pre = L;
while(r && P!=r) {
pre = r;
r = r->Next;
}
if(r==P) {
List p = (List)malloc(sizeof(struct LNode));
p->Data = X;
p->Next = r;
pre->Next = p;
return true;
}
printf("Wrong Position for Insertion\n");
return false;
}
bool Delete( List L, Position P )
{
List r = L;
List pre = L;
while(r && r!=P)
{
pre = r;
r = r->Next;
}
if(r==P) {
pre->Next = P->Next;
free(P);
List k = pre->Next;
return true;
}
printf("Wrong Position for Deletion\n");
return false;
}
P.S:這道題需要寫四個函數,分別是鏈表的置空,查詢某個元素,還有元素的插入和刪除,都是一些鏈表的基本操作,題中的鏈表是有頭節點的,而開始的題中的鏈表是沒有使用頭節點的,這個與前面的有一些區別,其實擁有頭節點的鏈表更容易操作,在插入時不用考慮是否是第一個結點了,更加好寫些,同樣要注意Find函數,它需要返回的是這個元素的Position,而它是一個指針變量,而不是代表其位置的整型變量。
4-7 在一個數組中實現兩個堆棧
P.S:很頭疼,這一題沒有通過,報的錯誤也是十分無奈,超時,所以也不知道怎樣去解決這個問題,如何去優化代碼,這道題其實是一個數組嘛,兩個棧的棧底在兩頭,設計應該就是這樣,但是給我報超時錯誤,暫時先放下吧,以後通過再補上來。
更新:補上成功的code,今天突然再次提交,居然就通過了,看來我的想法是沒有問題的^_^
code:
Stack CreateStack( int MaxSize )
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->MaxSize = MaxSize;
S->Data = (ElementType *)malloc(sizeof(ElementType)*MaxSize);
S->Top2 = MaxSize;
S->Top1 = -1;
return S;
}
bool Push(Stack S, ElementType X, int Tag){
if(S->Top1+1 == S->Top2){
printf("Stack Full\n");
return false;
}else{
if(Tag == 1){
S->Top1++;
S->Data[S->Top1] = X;
}else{
S->Top2--;
S->Data[S->Top2] = X;
}
}
return true;
}
ElementType Pop(Stack S, int Tag){
int X;
if(Tag == 1){
if(S->Top1 == -1){
printf("Stack 1 Empty\n");
return ERROR;
}else{
X = S->Data[S->Top1];
S->Top1--;
return X;
}
}else if(Tag == 2){
if(S->Top2 == S->MaxSize){
printf("Stack 2 Empty\n");
return ERROR;
}else{
X = S->Data[S->Top2];
S->Top2++;
return X;
}
}
}
4-8 求二叉樹高度
code:
int GetHeight( BinTree BT )
{
if (BT == NULL)
return 0;
else {
int left = GetHeight(BT->Left);
int right = GetHeight(BT->Right);
if(left>=right)
return 1 + left;
else
return 1 + right;
}
}
P.S:求一顆二叉樹的高度,我直接使用了遞歸實現,所以也十分的清晰易懂。
4-9 二叉樹遍歷
這道題吧,也木有通過,其實是不願寫吧,前序,中序,後續遍歷都很簡單,但是層序便利時,我們知道需要藉助隊列來實現,而在函數題中又不能用那種頭文件,因此我想了想,但後來腦子就不舒服,先放下,後面補上。
更新:今天想了想,其實沒有必要用隊列的,可以簡單點嘛,開始怎麼就那麼蠢呢,隊列也是由數組或鏈表構成的,而這道題又不需要考慮隊列滿或者空的情況,自己用一個數組代替不就是了,其實很簡單的啦,我才用了一個容量爲100的數組來模擬隊列,最後就這樣成功啦,前中後三種遍歷就沒有什麼好說的咯,遞歸,簡單易懂,用棧的話也不難,但是能簡單就簡單嘛
code:
void InorderTraversal( BinTree BT ){
if(BT){
InorderTraversal(BT->Left);
printf(" %c", BT->Data);
InorderTraversal(BT->Right);
}
}
void PreorderTraversal( BinTree BT ){
if(BT){
printf(" %c",BT->Data);
PreorderTraversal(BT->Left);
PreorderTraversal(BT->Right);
}
}
void PostorderTraversal( BinTree BT )
{
if(BT != NULL){
PostorderTraversal(BT->Left);
PostorderTraversal(BT->Right);
printf(" %c", BT->Data);
}
}
void LevelorderTraversal( BinTree BT ) {
BinTree str[100];
int rear = -1, front = -1;
BinTree T;
if(!BT)
return;
rear = rear+1;
str[rear] = BT;
while(rear != front){
front = front+1;
T = str[front];
printf(" %c", T->Data);
if(T->Left) {
rear = rear+1;
str[rear] = T->Left;
}
if(T->Right){
rear++ ;
str[rear] = T->Right;
}
}
}
4-10 二分查找
code:
Position BinarySearch( List Tbl, ElementType K )
{
int left, right, middle;
left = 1, right = Tbl->Last;
while (left <= right)
{
middle = (left + right) / 2;
if (Tbl->Data[middle] > K)
{
right = middle - 1;
}
else if (Tbl->Data[middle] < K)
{
left = middle + 1;
}
else if(Tbl->Data[middle] == K)
{
return middle;
}
}
return NotFound;
}
P.S:二分查找算法,也叫折半查找,也就是將數組每次只查找一半,因此可以省去很多的比較次數,也就提高了效率,減少了查找時間,是一個很好,很基礎的算法
*
4-11 先序輸出葉結點
code:
void PreorderPrintLeaves( BinTree BT ){
if(BT != NULL){
PreorderPrintLeaves(BT->Left);
if(BT->Data >='A' && BT->Data <='z' && BT->Left == NULL && BT->Right == NULL){
printf(" %c",BT->Data);
}
PreorderPrintLeaves(BT->Right);
}
}
P.S:先序輸出葉子結點,說白了就是先序遍歷唄,不過在先序遍歷的基礎上進行一下判斷,當左右子節點都爲空時才輸出來。
4-12 二叉搜索樹的操作集
P.S:這道題部分正確,可能是沒有考慮全面,前三個測試點不能通過,後兩個可以,所以等通過之後再放上代碼。
更新:調了很多次,這道雖然是教材上的,但是刪除操作是真的很複雜,需要很細心頭腦很清晰的去寫,下面的是code,參考了教材上的源碼,最後居然讓我發現了一個小錯誤,教材上查找最大最小元素函數的判斷語句中多了個“!”,很容易就發現啦,但是不一定會注意到,慢慢寫啦!!
code:
BinTree Insert( BinTree BST, ElementType X )
{
if(!BST) { /* 若原樹爲空,生成並返回一個結點的二叉搜索樹 */
BST = (BinTree)malloc(sizeof(struct TNode));
BST ->Data = X;
BST ->Left = BST ->Right = NULL;
}else { /* 開始尋找要插入元素的位置 */
if(X < BST ->Data ) {
BST ->Left = Insert(BST ->Left, X);
}else if(X > BST ->Data ) {
BST ->Right = Insert(BST ->Right, X);
}
/* X已經存在,不用操作 */
}
return BST;
}
BinTree Delete( BinTree BST, ElementType X )
{
Position Tmp;
if(!BST) {
printf("Not Found\n");
}else {
if( X < BST->Data) {
BST ->Left = Delete(BST->Left, X); /* 左子樹遞歸刪除 */
}else if(X > BST->Data ) {
BST ->Right = Delete(BST->Right , X); /* 右子樹遞歸刪除*/
}else { /* 找到需要刪除的結點 */
if(BST->Left && BST->Right) {
/* 被刪除的結點有左右子結點 */
Tmp = FindMin( BST ->Right); /* 在右子樹中找到最小結點填充刪除結點 */
BST ->Data = Tmp ->Data;
BST ->Right = Delete(BST ->Right, BST ->Data); /* 在刪除結點的右結點中刪除最小元素 */
}else { /* 被刪除結點有一個或沒有子結點*/
Tmp = BST;
if(!BST ->Left) { /*有右孩子或無子結點*/
BST = BST->Right;
}else if(!BST->Right) { /* 有左孩子或無子節點*/
BST = BST->Left;
}
free(Tmp);
}
}
}
return BST;
}
Position Find( BinTree BST, ElementType X )
{
if(!BST) {
return NULL; // 查找失敗
}
if(X > BST->Data) {
return Find(BST->Right, X); //在右子樹中繼續查找
}else if(X < BST->Data) {
return Find(BST->Left, X); //在左子樹中繼續查找
}else {
return BST; //查找成功
}
}
Position FindMin( BinTree BST )
{
if(BST) {
while(BST->Left) {
BST = BST->Left; //沿着左分支一直查找,直到葉子結點
}
}
return BST;
}
Position FindMax( BinTree BST )
{
if(BST) {
while(BST->Right) {
BST = BST->Right; //沿着右分支一直查找,直到葉子結點
}
}
return BST;
}
函數題就這12道,其中已經完全通過了9道,還有3道暫時沒有通過,要不超時,要不部分正確,暫時想也想不出來,想的也比較難過,所以等什麼時候有空無聊時再想想,然後通過了再補上吧,如果能給予想法的話請聯繫我呀,一起交流,一起分享,一起進步^_^
今天將原先沒放上的都解決啦,12道函數題完成,雖然都是很基礎的數據結構,但是真要全部靠自己寫出來很困難困難,多多練習咯,後面就慢慢刷編程題咯,刷題的快感~~~