第17章 高級數(shù)據(jù)表示

復(fù)習(xí)題

  1. 定義一種數(shù)據(jù)類型設(shè)計那些內(nèi)容?

    • 如何存儲數(shù)據(jù)
    • 如何對數(shù)據(jù)操作(管理數(shù)據(jù)的函數(shù))
  2. 什么是ADT

    • ADT(Abstract Data Type)抽象數(shù)據(jù)類型,是對一種類型屬性集和可以對該類型進(jìn)行的操作的正式定義瘪校。ADT應(yīng)該用一般語言表示澄暮,而不是某種特殊的計算機語言,而且不應(yīng)該包含實現(xiàn)細(xì)節(jié)。
  3. QueueIsEmpty()函數(shù)接受一個指向queue結(jié)構(gòu)的指針作為參數(shù)赏寇,但是也可以將其編寫成一個queue結(jié)構(gòu)作為參數(shù)吉嫩。這兩種方式有什么優(yōu)點。

    1.傳結(jié)構(gòu)優(yōu)點: 可以查看里面所有東西并且不會改變其中的內(nèi)容.
    缺點: 函數(shù)使用的是原始數(shù)據(jù)的副本嗅定。必須要有足夠的空間取存放他自娩。會浪費大量空間和時間

    1. 傳地址的優(yōu)點: 快、迅速
      缺點: 可能會改變里面的數(shù)據(jù)渠退,操作比較麻煩忙迁。不過可以const限定符解決問題

編程練習(xí)

1仿照書上的ADT main.h是書上的就不發(fā)了

#ifndef STACK_H_
#define STACK_H_
#include <stdbool.h>

#define TSIZE 40

typedef struct film
{
    char title[TSIZE];
    int rating;
} Item;

typedef struct node
{
    Item item;
    struct node * front;
    struct node * next;    //主要就是加個鏈接
} Node;

typedef Node * List;

/*函數(shù)原型*/

/*操作:                     初始化一個鏈表*/
/*前提條件:                  plist指向一個鏈表*/
/*后置條件:                 鏈表初始化為空*/
void InitializeList(List * plist);

/*操作:                     確定鏈表是否為空定義,plist指向一個已初始化的鏈表*/
/*后置條件:                 如果鏈表為空碎乃,該函數(shù)返回true;否則返回false*/
bool ListIsEmpty(const List * plist);

/*操作:                     確定鏈表是否已滿姊扔,plist指向一個已初始化的鏈表*/
/*后置條件:                 如果鏈表已滿,該函數(shù)返回真;否則返回假*/
bool ListIsFull(const List * plist);

/*操作:                     確定鏈表中的項數(shù)梅誓,plist指向一個已初始化的鏈表*/
/*后置條件:                 該函數(shù)返回鏈表中的項數(shù)*/
unsigned int ListItemCount(const List * plist);

/*操作:                     在鏈表末尾添加項*/
/*前提條件:                  item是一個待添加至鏈表的項,plist指向一個已經(jīng)初始化的鏈表*/
/*后置條件:                  如果可以恰梢,該函數(shù)在鏈表末尾添加一個項,且返回true梗掰;否則返回false*/
bool AddItem( Item item, List * plist);

/*操作:                     把函數(shù)作用域鏈表中的每一項*/
/*                          plist指向一個已初始化的鏈表*/
/*                          pfun指向一個函數(shù)嵌言,該函數(shù)接受一個Item類型的參數(shù),且無返回值*/
/*后置條件:                  pfun指向的函數(shù)作用于鏈表中的每一項一次*/
void Traverse(const List * plist, void(*pfun)(Item item));

/*操作:                     釋放已分配的內(nèi)存(如果有的話)*/
/*                          plist指向一個已初始化的鏈表*/
/*后置條件:                  釋放了位鏈表分配的所有內(nèi)容及穗,鏈表設(shè)置位空*/
void EmptyTheList(List * plist);

#endif
#include <stdio.h>
#include "tree.h"
#include <stdlib.h>
#include <string.h>

static void CopyToNode(Item item, Node * pnode);

void InitializeList(List * plist)
{
    *plist = NULL;
}

bool ListIsEmpty(const List * plist)
{
    if (*plist == NULL)
        return true;
    else 
        return false;
}

bool ListIsFull(const List * plist)
{
    Node * pt;
    bool full;

    pt = (Node *)malloc(sizeof(Node));
    if (pt == NULL)
        full = true;
    else 
        full = false;
    free(pt);

    return full;
}

unsigned int ListItemCount(const List * plist)
{
    int count = 0;
    Node * pnode = *plist;

    while (pnode != NULL)
    {
        count++;
        pnode = pnode->next;
    }
    
    return count;
}

bool AddItem( Item item, List * plist)
{
    Node * pnew;
    Node * scan = *plist;

    pnew = (Node *) malloc(sizeof(Node));
    if (pnew == NULL)
        return false;
    
    CopyToNode(item, pnew);
    pnew->next = NULL;
    
    if (scan == NULL)
    {
        pnew->front = NULL;
        *plist = pnew;
    }
    else
    {
        pnew->front = scan;
        while (scan->next != NULL)
        {   
            scan = scan->next;
            pnew->front = scan;
        }
        scan->next = pnew;
    }

    return true;
}

void Traverse(const List * plist, void(*pfun)(Item item))
{
    Node * pnode = *plist;
    Node * rnode;

    while (pnode != NULL)
    {
        rnode = pnode;
        (*pfun)(pnode->item);
        pnode = pnode->next;
    }

    while (rnode != NULL)
    {
        (*pfun)(rnode->item);
        rnode = rnode->front;
    }
}

void EmptyTheList(List * plist)
{
    Node * psave;

    while (*plist != NULL)
    {
        psave = (*plist)->next;
        free(*plist);
        *plist = psave;
    }
    
}

static void CopyToNode(Item item, Node * pnode)
{
    pnode->item = item;
}
不是遞歸

2

list.h

/**
 *  假設(shè)list.h(程序清單17.3)使用下面的list定義:
 *  typedef struct list
 *  {
 *      Node * head;
 *      Node * end;
 *  } List;
 *  重寫list.c(程序清單17.5)中的函數(shù)以適應(yīng)新的定義摧茴,并通過films.c(程序清單17.4)測試
 *  最終的代碼.
*/
#ifndef LIST_H_
#define LIST_H_
#include <stdbool.h>

#define TSIZE 40

typedef struct film
{
    char title[TSIZE];
    int rating;
} Item;

typedef struct node
{
    Item item;
    struct node * next;
} Node;

typedef struct list
{
    Node * head;        /*指向隊列首項的指針    */
    Node * end;         /*指向隊列尾項的指針    */
} List;


/*函數(shù)原型*/

/*操作:                     初始化一個鏈表*/
/*前提條件:                  plist指向一個鏈表*/
/*后置條件:                 鏈表初始化為空*/
void InitializeList(List * plist);

/*操作:                     確定鏈表是否為空定義,plist指向一個已初始化的鏈表*/
/*后置條件:                 如果鏈表為空埂陆,該函數(shù)返回true;否則返回false*/
bool ListIsEmpty(const List * plist);

/*操作:                     確定鏈表是否已滿苛白,plist指向一個已初始化的鏈表*/
/*后置條件:                 如果鏈表已滿,該函數(shù)返回真;否則返回假*/
bool ListIsFull(const List * plist);

/*操作:                     確定鏈表中的項數(shù)焚虱,plist指向一個已初始化的鏈表*/
/*后置條件:                 該函數(shù)返回鏈表中的項數(shù)*/
unsigned int ListItemCount(const List * plist);

/*操作:                     在鏈表末尾添加項*/
/*前提條件:                  item是一個待添加至鏈表的項,plist指向一個已經(jīng)初始化的鏈表*/
/*后置條件:                  如果可以购裙,該函數(shù)在鏈表末尾添加一個項,且返回true鹃栽;否則返回false*/
bool AddItem( Item * item, List * plist);

/*操作:                     把函數(shù)作用域鏈表中的每一項*/
/*                          plist指向一個已初始化的鏈表*/
/*                          pfun指向一個函數(shù)躏率,該函數(shù)接受一個Item類型的參數(shù),且無返回值*/
/*后置條件:                  pfun指向的函數(shù)作用于鏈表中的每一項一次*/
void Traverse(const List * plist, void(*pfun)(Item item));

/*操作:                     釋放已分配的內(nèi)存(如果有的話)*/
/*                          plist指向一個已初始化的鏈表*/
/*后置條件:                  釋放了位鏈表分配的所有內(nèi)容谍咆,鏈表設(shè)置位空*/
void EmptyTheList(List * plist);

#endif

list.c

#include <stdio.h>
#include "lish.h"
#include <stdlib.h>
#include <string.h>

static void CopyToNode(Item * item, Node * pnode);
static void DeleteAllNodes(Node * head);
void InitializeList(List * plist)
{
    plist->head = plist->end = NULL;
}

bool ListIsEmpty(const List * plist)
{
    if (plist->head == NULL)
        return true;
    else 
        return false;
}

bool ListIsFull(const List * plist)
{
    Node * pt;
    bool full;

    pt = (Node *)malloc(sizeof(Node));
    if (pt == NULL)
        full = true;
    else 
        full = false;
    free(pt);

    return full;
}

unsigned int ListItemCount(const List * plist)
{
    int count = 0;
    Node * pnode = plist->head;

    while (pnode != NULL)
    {
        count++;
        pnode = pnode->next;
    }
    
    return count;
}

bool AddItem( Item * item, List * plist)
{
    Node * pnew;
    pnew = (Node *) malloc(sizeof(Node));
    if (pnew == NULL)
        return false;
    
    CopyToNode(item, pnew);
    pnew->next = NULL;
    if (ListIsEmpty(plist))
        plist->head = pnew;
    else
        plist->end->next = pnew;
    plist->end = pnew;

    return true;
}

void Traverse(const List * plist, void(*pfun)(Item item))
{
    Node * pnode = plist->head;
    while (pnode != NULL)
    {
        (*pfun)(pnode->item);
        pnode = pnode->next;
    }
}

void EmptyTheList(List * plist)
{
    if (plist != NULL)
        DeleteAllNodes(plist->head);
    plist->head = NULL;
    plist->end = NULL;
}

static void DeleteAllNodes(Node * head)
{
    Node * pright;
    while (head != NULL)
    {
        pright = head->next;
        free(head);
        head = pright;
    }  
}



static void CopyToNode(Item * item, Node * pnode)
{
    pnode->item = *item;
}
//注意:感覺刪除那里不得行禾锤,請大家教教
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末私股,一起剝皮案震驚了整個濱河市摹察,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌倡鲸,老刑警劉巖供嚎,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡克滴,警方通過查閱死者的電腦和手機逼争,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劝赔,“玉大人誓焦,你說我怎么就攤上這事∽琶保” “怎么了杂伟?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長仍翰。 經(jīng)常有香客問我赫粥,道長,這世上最難降的妖魔是什么予借? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任越平,我火速辦了婚禮,結(jié)果婚禮上灵迫,老公的妹妹穿的比我還像新娘秦叛。我一直安慰自己,他們只是感情好龟再,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布书闸。 她就那樣靜靜地躺著,像睡著了一般利凑。 火紅的嫁衣襯著肌膚如雪浆劲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天哀澈,我揣著相機與錄音牌借,去河邊找鬼。 笑死割按,一個胖子當(dāng)著我的面吹牛膨报,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播适荣,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼现柠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弛矛?” 一聲冷哼從身側(cè)響起够吩,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎丈氓,沒想到半個月后周循,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體强法,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年湾笛,在試婚紗的時候發(fā)現(xiàn)自己被綠了饮怯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡嚎研,死狀恐怖蓖墅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情临扮,我是刑警寧澤置媳,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站公条,受9級特大地震影響拇囊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜靶橱,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一寥袭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧关霸,春花似錦传黄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至佳遣,卻和暖如春识埋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背零渐。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工窒舟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诵盼。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓惠豺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親风宁。 傳聞我的和親對象是個殘疾皇子洁墙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容