数据结构与算法分析-第3章

.title { text-align: center; margin-bottom: .2em }
.subtitle { text-align: center; font-size: medium; font-weight: bold; margin-top: 0 }
.todo { font-family: monospace; color: red }
.done { font-family: monospace; color: green }
.priority { font-family: monospace; color: orange }
.tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal }
.timestamp { color: #bebebe }
.timestamp-kwd { color: #5f9ea0 }
.org-right { margin-left: auto; margin-right: 0px; text-align: right }
.org-left { margin-left: 0px; margin-right: auto; text-align: left }
.org-center { margin-left: auto; margin-right: auto; text-align: center }
.underline { text-decoration: underline }
#postamble p,#preamble p { font-size: 90%; margin: .2em }
p.verse { margin-left: 3% }
pre { border: 1px solid #ccc; padding: 8pt; font-family: monospace; overflow: auto; margin: 1.2em }
pre.src { position: relative; overflow: visible; padding-top: 1.2em }
pre.src::before { display: none; position: absolute; background-color: white; top: -10px; right: 10px; padding: 3px; border: 1px solid black }
pre.src:hover::before { display: inline }
pre.src-asymptote::before { content: "Asymptote" }
pre.src-awk::before { content: "Awk" }
pre.src-C::before { content: "C" }
pre.src-clojure::before { content: "Clojure" }
pre.src-css::before { content: "CSS" }
pre.src-D::before { content: "D" }
pre.src-ditaa::before { content: "ditaa" }
pre.src-dot::before { content: "Graphviz" }
pre.src-calc::before { content: "Emacs Calc" }
pre.src-emacs-lisp::before { content: "Emacs Lisp" }
pre.src-fortran::before { content: "Fortran" }
pre.src-gnuplot::before { content: "gnuplot" }
pre.src-haskell::before { content: "Haskell" }
pre.src-hledger::before { content: "hledger" }
pre.src-java::before { content: "Java" }
pre.src-js::before { content: "Javascript" }
pre.src-latex::before { content: "LaTeX" }
pre.src-ledger::before { content: "Ledger" }
pre.src-lisp::before { content: "Lisp" }
pre.src-lilypond::before { content: "Lilypond" }
pre.src-lua::before { content: "Lua" }
pre.src-matlab::before { content: "MATLAB" }
pre.src-mscgen::before { content: "Mscgen" }
pre.src-ocaml::before { content: "Objective Caml" }
pre.src-octave::before { content: "Octave" }
pre.src-org::before { content: "Org mode" }
pre.src-oz::before { content: "OZ" }
pre.src-plantuml::before { content: "Plantuml" }
pre.src-processing::before { content: "Processing.js" }
pre.src-python::before { content: "Python" }
pre.src-R::before { content: "R" }
pre.src-ruby::before { content: "Ruby" }
pre.src-sass::before { content: "Sass" }
pre.src-scheme::before { content: "Scheme" }
pre.src-screen::before { content: "Gnu Screen" }
pre.src-sed::before { content: "Sed" }
pre.src-sh::before { content: "shell" }
pre.src-sql::before { content: "SQL" }
pre.src-sqlite::before { content: "SQLite" }
pre.src-forth::before { content: "Forth" }
pre.src-io::before { content: "IO" }
pre.src-J::before { content: "J" }
pre.src-makefile::before { content: "Makefile" }
pre.src-maxima::before { content: "Maxima" }
pre.src-perl::before { content: "Perl" }
pre.src-picolisp::before { content: "Pico Lisp" }
pre.src-scala::before { content: "Scala" }
pre.src-shell::before { content: "Shell Script" }
pre.src-ebnf2ps::before { content: "ebfn2ps" }
pre.src-cpp::before { content: "C++" }
pre.src-abc::before { content: "ABC" }
pre.src-coq::before { content: "Coq" }
pre.src-groovy::before { content: "Groovy" }
pre.src-bash::before { content: "bash" }
pre.src-csh::before { content: "csh" }
pre.src-ash::before { content: "ash" }
pre.src-dash::before { content: "dash" }
pre.src-ksh::before { content: "ksh" }
pre.src-mksh::before { content: "mksh" }
pre.src-posh::before { content: "posh" }
pre.src-ada::before { content: "Ada" }
pre.src-asm::before { content: "Assembler" }
pre.src-caml::before { content: "Caml" }
pre.src-delphi::before { content: "Delphi" }
pre.src-html::before { content: "HTML" }
pre.src-idl::before { content: "IDL" }
pre.src-mercury::before { content: "Mercury" }
pre.src-metapost::before { content: "MetaPost" }
pre.src-modula-2::before { content: "Modula-2" }
pre.src-pascal::before { content: "Pascal" }
pre.src-ps::before { content: "PostScript" }
pre.src-prolog::before { content: "Prolog" }
pre.src-simula::before { content: "Simula" }
pre.src-tcl::before { content: "tcl" }
pre.src-tex::before { content: "TeX" }
pre.src-plain-tex::before { content: "Plain TeX" }
pre.src-verilog::before { content: "Verilog" }
pre.src-vhdl::before { content: "VHDL" }
pre.src-xml::before { content: "XML" }
pre.src-nxml::before { content: "XML" }
pre.src-conf::before { content: "Configuration File" }
table { border-collapse: collapse }
caption.t-above { caption-side: top }
caption.t-bottom { caption-side: bottom }
td,th { vertical-align: top }
th.org-right { text-align: center }
th.org-left { text-align: center }
th.org-center { text-align: center }
td.org-right { text-align: right }
td.org-left { text-align: left }
td.org-center { text-align: center }
dt { font-weight: bold }
.footpara { display: inline }
.footdef { margin-bottom: 1em }
.figure { padding: 1em }
.figure p { text-align: center }
.inlinetask { padding: 10px; border: 2px solid gray; margin: 10px; background: #ffffcc }
#org-div-home-and-up { text-align: right; font-size: 70%; white-space: nowrap }
textarea { }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00 }
.org-info-js_info-navigation { border-style: none }
#org-info-js_console-label { font-size: 10px; font-weight: bold; white-space: nowrap }
.org-info-js_search-highlight { background-color: #ffff00; color: #000000; font-weight: bold }
.org-svg { width: 90% }
pre.src { background-color: #292b2e; color: #b2b2b2 }
pre.src { background-color: #292b2e; color: #b2b2b2 }

数据结构与算法分析-第3章

Table of Contents

  • 1. 第3章-表,栈和队列

    • 1.1. 抽象数据类型
    • 1.2. 表ADT
      • 1.2.1. 链表的实现
      • 1.2.2. 多项式ADT
      • 1.2.3. 游标实现
    • 1.3. 栈ADT
      • 1.3.1. 指针实现
      • 1.3.2. 数组实现
    • 1.4. 队列ADT
      • 1.4.1. 数组实现方式
      • 1.4.2. 链表实现方式

1 第3章-表,栈和队列

1.1 抽象数据类型

  • 抽象数据类型(abstract data type, ADT)是一些操作集合.抽象数据类型是数学的抽象

1.2 表ADT

1.2.1 链表的实现

  • linkedlist.h
#ifndef _LIST_H
#define _LIST_H
struct Node;
typedef struct Node* PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;

List MakeEmpty();
int IsEmpty(List L);
int IsLast(Position P, List L);
Position Find(int X, List L);
void Delete(int X, List L);
Position FindPrevious(int X, List L);
void Insert(int X, List L, Position P);
void DeleteList(List L);
Position Header(List L);
Position First(List L);
Position Advance(Position P);
int Reetireve(Position P);
void printLinkedList(List L);
void fromArray(List L, int[], int);

#endif

/* Place in the implementation file  */
struct Node
{
    int Element;
    Position Next;
};
  • linkedlist.c
#include "linkedlist.h"
#include <stdio.h>
#include <stdlib.h>

/* Return true if L is empty */
int
IsEmpty(List L) {
    return L->Next == NULL;
}

List
MakeEmpty() {
    List emptylist;

    emptylist = malloc(sizeof(struct Node));

    if (emptylist == NULL) {
        perror("out of memory");
    }

    return emptylist;
}

/* Return true if P is the last position in list i */
/* Parameter L is unused in this implementation */
int
IsLast(Position P, List L) {
    return P->Next == NULL;
}

/* Return Position of X in L; NULL if not found */
Position
Find(int X, List L) {
    Position P;

    P = L->Next;

    while (P != NULL && P->Element != X) {
        P = P->Next;
    }

    return P;
}

/* Delete first occurrence of X from a list */
/* Assume use of a header Node */
void
Delete(int X, List L) {
    Position P, TmpCell;
    P = FindPrevious(X, L);

    /* Assumption of header use */
    /* X is found; delete it */
    if (!IsLast(P, L)) {
        TmpCell = P->Next;
        /* Bypass deleted cell */
        P->Next = TmpCell->Next;
        free(TmpCell);
    }
}

/* If X is not found, then Next field of returned */
/* Position is NULL */
/* Assume a header */
Position
FindPrevious(int X, List L) {
    Position P;
    P = L;
    while(P->Next != NULL && P->Next->Element != X) {
        P = P->Next;
    }
    return P;
}

/* Insert (after legal position P) */
/* Header implementation assumed */
/* Parameter L is unused in this implementation */
void
Insert(int X, List L, Position P) {
    Position TmpCell;

    TmpCell = malloc(sizeof(struct Node));
    if (TmpCell == NULL) {
        perror("Out of space!!!");
    }

    TmpCell->Element = X;
    TmpCell->Next = P->Next;
    P->Next = TmpCell;
}

/* Correct DeleteList algorithm */
void
DeleteList(List L) {
    Position P, Tmp;

    /* Header assumed */
    P = L->Next;
    L->Next = NULL;
    while(P != NULL) {
        Tmp = P->Next;
        // after free P we can‘t use P
        free(P);
        P = Tmp;
    }
}

Position
Header(List L) {
    return L;
}

Position
First(List L) {
    return L->Next;
}

Position
Advance(Position P) {
    return P->Next;
}

int Retrieve(Position P) {
    return P->Element;
}

void
printLinkedList(List L) {
    // skip header
    Position P = L->Next;
    printf("[ ");
    while (P != NULL) {
        printf("%d ", P->Element);
        P = P->Next;
    }
    printf("]\n");
}

void
fromArray(List L, int args[], int size) {
    if (L == NULL) {
        L = MakeEmpty();
    }
    Position P = L;
    Position tmp;
    for (int i = 0; i < size; i++) {
        tmp = malloc(sizeof(struct Node));
        if (tmp == NULL) {
            perror("out of memory");
        }
        tmp->Element = args[i];
        P->Next = tmp;
        P = P->Next;
    }
}

1.2.2 多项式ADT

  • polynomial.h
#ifndef _POLYNOMIAL_H
#define _POLYNOMIAL_H

#define  MaxDegree 1000

/* array way */
typedef struct {
    int CoeffArray[MaxDegree + 1];
    int HighPower;
} * Polynomial;

typedef struct Node *PtrToNode;

struct Node {
    int Cofficient;
    int Exponent;
    PtrToNode Next;
};

/* Nodes sorted by exponent */
/* typedef PtrToNode Polynomial; */

void
ZeroPolynomial(Polynomial Poly);

void
AddPolynomial(const Polynomial Poly1, const Polynomial Poly2, Polynomial PolySum);

void
MultPolynomial(const Polynomial Poly1, const Polynomial Poly2, Polynomial PolyProd);

#endif
  • polynomial.c
#include "polynomial.h"
#include "utils.h"
#include <stdio.h>

void ZeroPolynomial(Polynomial poly) {
    for(int i = 0; i < MaxDegree; i++) {
        poly->CoeffArray[i] = 0;
    }
    poly->HighPower = 0;
}

void
AddPolynomial(const Polynomial Poly1,
              const Polynomial Poly2, const Polynomial PolySum) {
    int i;
    ZeroPolynomial(PolySum);
    PolySum->HighPower = Max(Poly1->HighPower, Poly2->HighPower);

    for(i = PolySum->HighPower; i >= 0; i--) {
        PolySum->CoeffArray[i] = Poly1->CoeffArray[i] + Poly2->CoeffArray[i];
    }
}

void
MultPolynomial(const Polynomial Poly1,
               const Polynomial Poly2, const Polynomial PolyProd) {
    int i, j;
    ZeroPolynomial(PolyProd);
    PolyProd->HighPower = Poly1->HighPower + Poly2->HighPower;

    if (PolyProd->HighPower > MaxDegree) {
        perror("Exceeded array size");
    } else {
        for (int i = 0; i <= Poly1->HighPower; i++) {
            for (int j = 0; j <= Poly2->HighPower; j++) {
                PolyProd->CoeffArray[i + j] +=
                    Poly1->CoeffArray[i] *
                    Poly2->CoeffArray[j];
            }
        }
    }
}

1.2.3 游标实现

  • 游标有一个全局的结构体数组, 数组下标用来代表一个地址.
  • 使用数组来模拟malloc和free.
  • 数组0索引管理着链表的空闲内存.
  • 没有可用空间,将P置为0实现.
  • cursor.h
#ifndef _CURSOR_H
#define _CURSOR_H

#define SpaceSize 13

typedef int PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
typedef int ElementType;

void InitializeCursorSpace(void);

List MakeEmpty(List L);
int IsEmpty(const List L);
int IsLast(const Position P, const List L);
Position Find(ElementType X, List L);
void Delete(ElementType X, List L);
Position FindPrevious(ElementType X, const List L);
void Insert(ElementType X, List L, Position P);
void DeleteList(List L);
Position Header(const List L);
Position First(const List L);
Position Advance(const Position P);
ElementType Retireve(const Position P);
List FromArray(int[], int);
void PrintCursorList(List);

struct Node {
    ElementType Element;
    Position Next;
};

#endif
  • cursor.c
#include "cursor.h"
#include <stdio.h>

/* Place in implementation file */

struct Node CursorSpace[SpaceSize];

static Position
CursorAlloc(void) {
    Position P;

    P = CursorSpace[0].Next;
    CursorSpace[0].Next = CursorSpace[P].Next;

    return P;
}

static void
CursorFree(Position P) {
    CursorSpace[P].Next = CursorSpace[0].Next;
    CursorSpace[0].Next = P;
}

void
InitializeCursorSpace(void) {
    for (int i = 0; i < SpaceSize - 1; i++) {
        CursorSpace[i].Next = i + 1;
    }
    CursorSpace[SpaceSize - 1].Next = 0;
}

List
MakeEmpty(List L) {
    if (IsEmpty(L)) {
        return L;
    }

    Position p = CursorSpace[L].Next;
    Position tmp;
    while(p) {
        tmp = p;
        p = CursorSpace[p].Next;
        CursorFree(tmp);
    }
    return L;
}

/* Return true if L is empty */
int
IsEmpty(List L) {
    return CursorSpace[L].Next == 0;
}

/* Return true if P is the last position in list l */
/* Parameter L is unused in this implementation */
int
IsLast(Position P, List L) {
    return CursorSpace[P].Next == 0;
}

/* Return Position of X in L; 0 if not found */
/* Uses a header node */
Position
Find(ElementType X, List L) {
    Position P;
    P = CursorSpace[L].Next;
    while (P && CursorSpace[P].Element != X) {
        P = CursorSpace[P].Next;
    }
    return P;
}

/* Delete first occurrence of X from a list */
/* Assume use of a header node */
void
Delete(ElementType X, List L) {
    Position P, TmpCell;

    P = FindPrevious(X, L);

    /* Assumption of header use */
    /* X is found; delete it */
    if (!IsLast(P, L)) {
        TmpCell = CursorSpace[P].Next;
        CursorSpace[P].Next = CursorSpace[TmpCell].Next;
        CursorFree(TmpCell);
    }
}

Position
FindPrevious(ElementType X, const List L) {
    Position p, tmp;
    tmp = CursorSpace[L].Next;
    while(tmp && CursorSpace[tmp].Element != X) {
        // record
        p = tmp;
        tmp = CursorSpace[tmp].Next;
    }
    return p;
}

/* Insert (after legal position P) */
/* Header implementation assumed */
/* Parameter L is unused in this implementation */
void
Insert(ElementType X, List L, Position P) {
    Position TmpCell;

    TmpCell = CursorAlloc();
    if (TmpCell == 0) {
        perror("out of memory");
    }
    CursorSpace[TmpCell].Element = X;
    CursorSpace[TmpCell].Next = CursorSpace[P].Next;
    CursorSpace[P].Next = TmpCell;
}

void DeleteList(List L) {
    List head = MakeEmpty(L);
    CursorFree(head);
}

Position
Header(const List L) {
    return L;
}

Position
First(const List L) {
    return CursorSpace[L].Next;
}

Position
Advance(const Position P) {
    return CursorSpace[P].Next;
}

ElementType
Retireve(const Position P) {
    return CursorSpace[P].Element;
}

List
FromArray(int args[], int size) {
    List list = CursorAlloc();
    Position p = list;
    for (int i = 0; i < size; i++) {
        Insert(args[i], list, p);
        p = CursorSpace[p].Next;
    }
    CursorSpace[p].Next = 0;
    return list;
}

void
PrintCursorList(List l) {
    printf("[ ");
    Position p = CursorSpace[l].Next;
    while(p) {
        printf("%d ", CursorSpace[p].Element);
        p = CursorSpace[p].Next;
    }
    printf("]\n");
}

1.3 栈ADT

  • FILO(先进后出)
  • 实现方法
    • 指针实现
    • 数组实现

1.3.1 指针实现

#ifndef _STACK_H
#define _STACK_H

struct Node;
typedef struct Node *PtrNode;
typedef PtrNode Stack;
typedef int ElementType;

int IsEmpty(Stack S);
Stack CreateStack(void);
void DisposeStack(Stack S);
void MakeEmpty(Stack S);
void Push(ElementType X, Stack S);
ElementType Top(Stack S);
void Pop(Stack S);

#endif
#include "stackwithlist.h"
#include <stdio.h>
#include <stdlib.h>

struct Node {
    ElementType Element;
    PtrNode Next;
};

int
IsEmpty(Stack S) {
    return S->Next == NULL;
}

Stack CreateStack(void) {
    Stack S;

    S = malloc(sizeof(struct Node));
    if (S == NULL) {
        perror("out of memory");
    }
    S->Next = NULL;
    MakeEmpty(S);
    return S;
}

void
MakeEmpty(Stack S) {
    if (S == NULL) {
        perror("Must use CreateStack first");
    } else {
        while (!IsEmpty(S)) {
            Pop(S);
        }
    }
}

void
Push(ElementType X, Stack S) {
    PtrNode TmpCell;

    TmpCell = malloc(sizeof(struct Node));
    if (TmpCell == NULL) {
        perror("out of memory");
    } else {
        TmpCell->Element = X;
        TmpCell->Next = S->Next;
        S->Next = TmpCell;
    }
}

ElementType
Top(Stack S) {
    if (!IsEmpty(S)) {
        return S->Next->Element;
    }
    printf("empty Stack");
    /* Return value used to avoid warning */
    return 0;
}

void
Pop(Stack S) {
    PtrNode FirstCell;
    if (IsEmpty(S)) {
        perror("Empty Stack");
    } else {
        FirstCell = S->Next;
        S->Next = S->Next->Next;
        free(FirstCell);
    }
}

void
DisposeStack(Stack S) {
    MakeEmpty(S);
    free(S);
}

1.3.2 数组实现

#ifndef _STACKWITHARRAY_H
#define _STACKWITHARRAY_H

struct StackRecord;
typedef struct StackRecord* Stack;
typedef int ElementType;

int IsEmpty(Stack S);
int IsFull(Stack S);
Stack CreateStack(int MaxElements);
void DisposeStack(Stack S) ;
void MakeEmpty(Stack S);
void Push(ElementType X, Stack S);
ElementType Top(Stack S);
void Pop(Stack S);
ElementType TopAndPop(Stack S);

struct StackRecord {
    int Capacity;
    int TopOfStack;
    ElementType *Array;
};

#endif
#include "stackwitharray.h"
#include <stdio.h>
#include <stdlib.h>

#define EmptyTOS (-1)
#define MinStackSize (5)

Stack
CreateStack(int MaxElements) {
    Stack S;

    if (MaxElements < MinStackSize) {
        perror("Stack size is too small");
    }

    S = malloc(sizeof(struct StackRecord));
    if (S == NULL) {
        perror("Out of space!!!");
    }

    S->Array = malloc(sizeof(ElementType) * MaxElements);
    if (S->Array == NULL) {
        perror("Out of space!!!");
    }
    S->Capacity = MaxElements;
    MakeEmpty(S);
    return S;
}

void
DisposeStack(Stack S) {
    if (S != NULL) {
        free(S->Array);
        free(S);
    }
}

int
IsEmpty(Stack S) {
    return S->TopOfStack == EmptyTOS;
}

void
MakeEmpty(Stack S) {
    S->TopOfStack = EmptyTOS;
}

void
Push(ElementType X, Stack S) {
    if (IsFull(S)) {
        perror("Full Stack");
    } else {
        S->Array[++S->TopOfStack] = X;
    }
}

int
IsFull(Stack S) {
    return S->TopOfStack == S->Capacity;
}

ElementType
Top(Stack S) {
    if (!IsEmpty(S)) {
        return S->Array[S->TopOfStack];
    }
    perror("Empty Stack");
    /* Return value used to avoid warning */
    return 0;
}

void
Pop(Stack S) {
    if (IsEmpty(S)) {
        perror("Empty Stack");
    } else {
        S->TopOfStack--;
    }
}

ElementType
TopAndPop(Stack S) {
    if (!IsEmpty(S)) {
        return S->Array[S->TopOfStack--];
    }
    perror("Empty Stack");
    /* Return value used to avoid warning */
    return 0;
}

1.4 队列ADT

  • FIFO(先进先出)

1.4.1 数组实现方式

  • queuewitharray.h
#ifndef _QUEUEWITHARRAY_H
#define _QUEUEWITHARRAY_H

struct QueueRecord;
typedef struct QueueRecord *Queue;
typedef int ElementType;

int IsEmpty(Queue Q);
int IsFull(Queue Q);
Queue CreateQueue(int MaxElements);
void DisposeQueue(Queue Q);
void MakeEmpty(Queue Q);
void Enqueue(ElementType X, Queue Q);
ElementType Front(Queue Q);
void Dequeue(Queue Q);
ElementType FrontAndDequeue(Queue Q);

/* Queue implementation is a dynamically allocated array */
#define MinQueueSize (5)
struct QueueRecord {
    int Capacity;
    int Front;
    int Rear;
    int Size;
    ElementType *Array;
};

#endif
  • queuewitharray.c
#include <stdio.h>
#include <stdlib.h>
#include "queuewitharray.h"

int
IsEmpty(Queue Q) {
    return Q->Size == 0;
}

int
IsFull(Queue Q) {
    return Q->Size == Q->Capacity;
}

Queue
CreateQueue(int MaxElements) {
    Queue Q;
    Q = malloc(sizeof(Queue));
    if (Q == NULL) {
        perror("create Queue failed!!!");
    }
    Q->Array = malloc(sizeof(ElementType)*MaxElements);
    if (Q->Array == NULL) {
        perror("create Array failed!!!");
    }
    Q->Capacity = MaxElements;
    MakeEmpty(Q);
    return Q;
}

void
DisposeQueue(Queue Q) {
    free(Q->Array);
    free(Q);
}

void
MakeEmpty(Queue Q) {
    Q->Size = 0;
    Q->Front = 1;
    Q->Rear = 0;
}

static int
Succ(int Value, Queue Q) {
    if (++Value == Q->Capacity) {
        Value = 0;
    }
    return Value;
}

void
Enqueue(ElementType X, Queue Q) {
    if (IsFull(Q)) {
        perror("Full queue");
    } else {
        Q->Size++;
        Q->Rear = Succ(Q->Rear, Q);
        Q->Array[Q->Rear] = X;
    }
}

ElementType
Front(Queue Q) {
    return Q->Array[Q->Front];
}

void
Dequeue(Queue Q) {
    if (IsEmpty(Q)) {
        perror("Empty Queue!!!");
    }
    Q->Size--;
    Q->Front = Succ(Q->Front, Q);
}

ElementType
FrontAndDequeue(Queue Q) {
    if (IsEmpty(Q)) {
        perror("Empty Queue!!!");
    }
    Q->Size--;
    ElementType res = Q->Array[Q->Front];
    Q->Front = Succ( Q->Front, Q );
    return res;
}

1.4.2 链表实现方式

  • queuewithlist.h
#ifndef _QUEUEWITHLIST_H
#define _QUEUEWITHLIST_H

struct Queue;
struct Node;
typedef struct Node* Pnode;
typedef struct QueueRecord *Queue;
typedef int ElementType;

int IsEmpty(Queue Q);
Queue CreateQueue();
void DisposeQueue(Queue Q);
void Enqueue(ElementType X, Queue Q);
ElementType Front(Queue Q);
void Dequeue(Queue Q);
ElementType FrontAndDequeue(Queue Q);

struct QueueRecord {
    Pnode Front;
    Pnode Rear;
    int Size;
};

struct Node {
    ElementType Element;
    struct Node *Next;
};

#endif
  • queuewithlist.c
#include "queuewithlist.h"
#include <stdio.h>
#include <stdlib.h>

int
IsEmpty(Queue Q) {
    return Q->Size == 0;
}

Queue
CreateQueue() {
    Queue Q;
    Q = malloc(sizeof(struct QueueRecord));
    if (Q == NULL) {
        perror("create queue fail!!!");
    }
    Q->Size = 0;
    Q->Front = malloc(sizeof(struct Node));
    if (Q->Front == NULL) {
        printf("create front fail");
        exit(-1);
    }
    Q->Rear = Q->Front;
    Q->Front->Next = NULL;
    printf("创建队列成功\n");
    return Q;
}

void
DisposeQueue(Queue Q) {
    Pnode n = Q->Front;
    Pnode tmp = n;
    while (n != NULL) {
        tmp = n->Next;
        free(n);
        n = tmp;
    }
    free(Q);
    printf("销毁队列成功\n");
}

void
Enqueue(ElementType X, Queue Q) {
    Pnode P;
    P = malloc(sizeof(struct Node));
    if (P == NULL) {
        printf("create node fail");
        exit(-1);
    }
    P->Element = X;
    P->Next = Q->Rear->Next;
    Q->Rear->Next = P;
    Q->Rear = Q->Rear->Next;
    Q->Size++;
}

void
Dequeue(Queue Q) {
    if (IsEmpty(Q)) {
        printf("Empty Queue!!!");
        exit(-1);
    }
    Q->Front = Q->Front->Next;
    Q->Size--;
}

ElementType
FrontAndDequeue(Queue Q) {
    if (IsEmpty(Q)) {
        printf("Empty Queue!!!");
        exit(-1);
    }
    ElementType res = Q->Front->Element;
    Q->Front = Q->Front->Next;
    Q->Size--;
    return res;
}

Date: 2018-11-17 11:45

Author: devinkin

Created: 2018-11-17 六 11:47

Validate

原文地址:https://www.cnblogs.com/devinkin/p/9973366.html

时间: 2024-10-14 00:05:04

数据结构与算法分析-第3章的相关文章

《数据结构与算法分析-第2章-算法分析》

2.1 数学基础 1. 掌握O(N)的概念 2. 在需要大O表示的任何分析中,各种简化都是可能发生的,低阶项一般都会被自动忽略,常数也可以弃掉 2.2 模型 1. 对模拟机做的假设: 1. 模拟机做任何一件简单的工作(加法,减法,赋值,比较)都恰好花费一个时间单元 2. 模拟机有无限的内存,不会发生缺页中断 2.3 要分析的问题 若无相关的指定,则所需要的量是最坏情况下的运行时间 例子:最大子序列和问题的三种解法时间复杂度的分析 一般来说,数据的读入是一个瓶颈,只要可能,使得算法足够有效且不会导

数据结构与算法分析——第七章 排序

7.1 预备知识 1,算法接收 含元素的数组和包含元素个数的整数 2,基于比较的排序 7.2 插入排序 代码实现 void InsertionSort(ElementType A[],int N) { int i,j; ElementType Tmp; for(i = 1 ; i < N ; i++) { Tmp = A[i]; for(j = i ; j > 0 && A[j - 1] > Tmp ; j--) { A[j] = A[j - 1]; } A[j] = T

《数据结构与算法分析:C语言描述》复习——第四章“树”——AVL树

2014.06.15 16:22 简介: AVL树是一种高度平衡的二叉搜索树,其命名源自于联合发明算法的三位科学家的名字的首字母.此处“平衡”的定义是:任意节点的左右子树的高度相差不超过1.有了这个平衡的性质,使得AVL树的高度H总是接近log(N),因此各种增删改查的操作的复杂度能够保证在对数级别.没有bad case是AVL树与普通的二叉搜索树的最大区别.为了实现平衡性质,我们需要记录每个节点的高度(或者平衡因子)来检测不平衡的情况.为了修正高度不平衡,需要用到“旋转”的方法,分为单旋转和双

《数据结构与算法分析:C语言描述》复习——第六章“排序”——冒泡排序

2014.06.17 01:04 简介: 冒泡排序是O(n^2)级别的交换排序算法,原理简单,属于必知必会的基础算法之一. 思路: 排序要进行N轮,每一轮从尾部逐个向前扫描,遇到逆序对就进行交换.确保每一轮把最小的元素交换到前面去.这个过程好比水中的气泡向上飘,所以叫冒泡排序.代码非常简单,所以语言描述反而显得麻烦了. 实现: 1 // My implementation for bubble sort. 2 #include <iostream> 3 #include <vector&

《数据结构与算法分析:C语言描述》复习——第九章“图论”——无权值的最短路径问题

2014.07.04 18:24 简介: 给定一个有向图,你可以认为每条边长度都是1(所以叫无权值).下面的算法可以求出从特定的起点到终点的最短路径长度. 描述: 从起点出发,根据当前顶点出发的边进行广度优先搜索,直至找到终点即可.如果搜索结束了仍然没有找到终点,那么起点无法到达终点. 实现: 1 // A simple illustration for unweighted shortest path. Graph represented by adjacency matrix. 2 #inc

《数据结构与算法分析:C语言描述》复习——第五章“堆”——二叉堆

2014.06.15 22:14 简介: 堆是一种非常实用的数据结构,其中以二叉堆最为常用.二叉堆可以看作一棵完全二叉树,每个节点的键值都大于(小于)其子节点,但左右孩子之间不需要有序.我们关心的通常只有堆顶的元素,而整个堆则被封装起来,保存在一个数组中. 图示: 下图是一个最大堆: 实现: 优先队列是STL中最常用的工具之一,许多算法的优化都要利用堆,使用的工具就是优先队列.STL中的优先队列通过仿函数来定义比较算法,此处我偷懒用了“<”运算符.关于使用仿函数的好处,我之后如果有时间深入学习S

《数据结构与算法分析—C语言描述》pdf

下载地址:网盘下载 内容简介 编辑 <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行时间分析的基础上考查了一些高级数据结构,从历史的角度和近年的进展对数据结构的活跃领域进行了简要的概括.由于<数据结构与算法分析:C语言描述(原书第2版)>选材新颖,方法实用,题例丰富,取舍得当.<数据结构与算法分析:C语言描述(原书第2版)>的目的是培养学生良好的程序设计技巧和熟练的算

&lt;数据结构与算法分析 C++描述&gt;算法分析之最大子序列和问题

声明:这个系列博客是<数据结构与算法分析 C++描述>的读书笔记系列 参考博客:点击打开链接 本文是原书第二章内容,主要内容包括:算法的时间复杂度分析/算法的优化,分析的例子是很出名的最大子序列求和问题. 分为了四种方法来求解:穷举/穷举优化/递归(分治)/联机算法(动态规划), 算法复杂度为O(N^3)/O(N^2)/O(N*logN)/O(N). 思路都在具体代码里 ----------------------------------------代码如下------------------

数据结构与算法分析 c语言描述 pdf 高清下载

网盘下载:数据结构与算法分析 c语言描述 pdf 高清下载 – 易分享电子书PDF资源网 作者: [美] Mark Allen Weiss 出版社: 机械工业出版社 副标题: C语言描述 原作名: Data Structures and Algorithm Analysis in C:Second Edition 译者: 冯舜玺 出版年: 2004-1-1 页数: 391 定价: 35.00元 装帧: 平装 内容简介 · · · · · · 本书是<Data Structures and Alg