嵌入式day18

隊列的鏈式存儲

typedef int datatype;                       //定義鏈隊列中數據元素的數據類型
typedef struct node{
 datatype data;                 //數據域
 struct node *next;         //鏈接指針域
}linklist;       //鏈表元素類型定義
typedef struct{
 linklist *front, *rear;                     //鏈表元素類型定義
}linqueue;                               //鏈隊列類型定義
linkqueue *q;                        //定義指向連隊列的指針

  1. 先寫頭文件linkqueue.h
#ifndef _LINKQUEUE_H__
#define _LINKQUEUE_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int data_t;   //定義數據類型爲int//定義鏈式隊列的結點類型
typedef struct linkqueuenode{
 data_t data;
 struct linkqueuenode *next;
}linkqueue_node, *linkqueue_pnode;//將front和rear指針封裝
typedef struct linkqueue
{
 linkqueue_pnode front, rear;
}link_queue, *link_pqueue;
extern void init_linkqueue(link_pqueue *Q);
extern bool in_linkqueue(data_t data, link_pqueue q);
extern bool is_empty_linkqueue(link_pqueue q);
extern bool out_linkqueue(link_pqueue q, data_t *D);
extern void show_linkqueue(link_pqueue q);
  1. 寫linkqueue.c
#include "linkqueue.h"
void init_linkqueue(link_pqueue *Q)
{
 *Q = (link_pqueue)malloc(sizeof(link_queue));
 if(NULL == (*Q)){
 perror("malloc");
 exit(-1);
 }
 //申請頭結點空間
 (*Q)->front = (linkqueue_pnode)malloc(sizeof(linkqueue_node));
 if(NULL == (*Q)->front){
 perror("malloc");
 exit(-1);
 }
 (*Q)->front->next = NULL;
 (*Q)->rear = (*Q)->front;
}
//入隊
bool in_linkqueue(data_t data, link_pqueue q)
{
 linkqueue_pnode new;
 new = (linkqueue_pnode)malloc(sizeof(linkqueue_node));
 if(NULL == new){
 printf("入隊失敗!\n");
 return false;
 }
 new->data = data;
 new->next = q->rear->next;
 q->rear->next = new;
 q->rear = q->rear->next;
 return true;
}
bool is_empty_linkqueue(link_pqueue q)
{
 if(q->rear == q->front)
 return true;
 else
 return false;
}
bool out_linkqueue(link_pqueue q, data_t *D)
{
 linkqueue_pnode t;
 if(is_empty_linkqueue(q)){
 printf("隊列已空!\n");
 return false;
 }
 t = q->front;
 q->front = q->front->next;
 *D = q->front->data;
 free(t);
 return true;
}
void show_linkqueue(link_pqueue q)
{
 linkqueue_pnode p;
 for(p= q->front->next;p!= NULL;p=p->next)
 printf("%d\t", p->data);
 printf("\n");
}
  1. 寫測試程序test.c
/*
 *用鏈式隊列實現如下功能:用戶從鍵盤輸入整數,程序將其入隊,用戶輸入字母,程序將隊頭元素出隊,並在每一次出隊和入隊之後打印隊列元素。
 */
#include "linkqueue.h"
int main(void)
{
 link_pqueue q;
 data_t data, t;
 int ret;
 init_linkqueue(&q);
 while(1){
 printf("請輸入一個整數:");
 ret = scanf("%d", &data);
 if(ret == 1){
 if(in_linkqueue(data, q))
 show_linkqueue(q);
 }else{
 if(out_linkqueue(q, &t)){
 printf("out:%d\n", t);
 show_linkqueue(q);
 } 
 while(getchar()!= '\n');
 }
 }
 return 0;
}
  1. 寫Makefile文件
CC = gcc
CFLAGS = -Wall -g -o0
SRC = linkqueue.c test.c
OBJS = test
$(OBJS):$(SRC)
 $(CC) $(CFLAGS) -o $@ $^
.PHONY:
 clean
clean:
 $(RM) $(OBJS) .*.sw?

結果:

樹與二叉樹

  • 樹的基本概念

  • 二叉樹的概念

  • 二叉樹的性質

  • 二叉樹的順序存儲

  • 二叉樹的鏈式存儲

  • 二叉樹的遍歷

樹(Tree)是n(n≥0)個節點的有限集合T,它滿足兩個條件:

  • 有且僅有一個特定的稱爲根(Root)的節點

  • 其餘的節點可以分爲m(m≥0)個互不相交的有限集合T1、T2、…、Tm,其中每一個集合又是一棵樹,並稱爲其根的子樹(Subtree)。

樹的定義是遞歸定義

  • 一個節點的個數稱爲該結點的度數,一棵樹的度數是指該樹中最大度數。

  • 讀書爲零的節點稱爲樹葉或終端節點,度數不爲零的節點稱爲分支節點,除根節點外的分支結點稱爲內部節點。

  • 一個節點的子樹之根結點稱爲該節點的子結點,該節點稱爲它們的父節點,同一節點的各個子節點之間稱爲兄弟節點。一棵樹的根結點沒有父節點,葉節點沒有子節點。

  • 一個節點系列k1、k2、…、kj,並滿足ki是ki+1的父節點,就稱爲一條從k1到kj的路徑,路徑的長度爲j-1,即路徑中的邊數。路徑中前面的節點是後面節點的祖先,後面節點是前面節點的子孫。

  • 節點的層數等於父節點的層數加一,根節點的層數定義爲一。樹中節點層數最大值稱爲該樹的高度或深度。

  • 若書中每個節點的各個子樹的排列爲從左到右,不能交換,即兄弟之間是有序的,則該樹稱爲有序樹。一般的樹是有序樹。

  • m(m≥0)棵互不相交的的樹的集合稱爲森林。樹去掉根節點就成爲森林,森林加上一個新的根節點就成爲樹。

  • 樹的邏輯結構:樹中任何節點都可以有零個或多個直接後繼節點(子節點),但至多隻有一個直接前趨節點(父節點),根節點沒有前趨節點,葉節點沒有後繼節點。

二叉樹的概念

二叉樹是n(n≥0)個節點的有限集合,它或者是空集(n=0),或者是由一個根節點以及兩棵互不相交的、分別稱爲左子樹和右子樹的二叉樹組成。二叉樹與普通書有序數不同,二叉樹嚴格區分左孩子和右孩子,即使只有一個子節點也要區分左右。

二叉樹的性質

  • 二叉樹第i(i≥1)層上的節點最多爲2i-1個。

  • 深度爲k(k≥1)的二叉樹最多有2k-1個節點。

  • 在任意一棵二叉樹中,樹葉的數目比度數爲2的節點的數目多一。

    假設:度爲0的節點爲n0個,度爲1的節點爲n1個,度爲2的節點爲n2個。

    總結點數爲各類節點數之和:n = n0 + n1 + n2

    總結點數爲所有子節點數加一:n = n1 + 2*n2 + 1

    故得:n0 = n2 + 1 //(在二叉樹中,度爲0的節點總是比度爲2的節點多一)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章