考研数据结构

线性表

顺序表

  • 结构体
#define SequenceMaxsize 100
typedef int ElementType;

//TODO: 数组静态分配
typedef struct {
    ElementType data[SequenceMaxsize];
    int size;
} SqList_Static;

//TODO: 数组动态分配
//typedef struct {
//    ElementType *data;
//    int length;
//} SqList_Dynamic;
  • 具体函数实现
/**
 * 前插
 * @param sqList
 * @param i
 * @param e
 */
bool ListInsert(SqList_Static *sqList, int i, ElementType e) {
    if (i < 0 || i >= sqList->size + 1) return false;
    if (sqList->size == SequenceMaxsize) return false;
    for (int j = sqList->size; j >= i; j--) {
        sqList->data[j] = sqList->data[j - 1];
    }
    sqList->data[i] = e;
    sqList->size++;
    return true;
}
/**
 * 构造函数,使得线性表大小等于0
 * @param sqList 线性表对象
 */
void InitList(SqList_Static *sqList) {
    sqList->size = 0;
    FILE *file = fopen("E:\\DataStructure\\PostGraduate\\LinearList\\text", "r");
    if (file==NULL){
        printf("file open error!");
        return;
    } else{
        char ch[1024];
        int i = 0;
        while (!feof(file)) {
            fgets(ch, 1024, file);
            //ch[strlen(ch) - 1] = '\0';
            //printf("%s\n", ch);
            ListInsert(sqList, i, atoi(ch));
            i++;
        }
        fclose(file);
    }
}
/**
 * 输出
 * @param sqList 
 */
void PrintList(SqList_Static sqList) {
    for (int i = 0; i < sqList.size; i++) {
        printf("%d ", sqList.data[i]);
    }
}
/**
 * 取值
 * @param sqList 
 * @param i 
 * @return 
 */
ElementType GetElem(SqList_Static sqList, int i) {
    return sqList.data[i];
}

/**
 * 判空
 * @param sqList 
 * @return 
 */
bool Empty(SqList_Static sqList) {
    return (sqList.size == 0) ? true : false;
}
/**
 * 长度
 * @param sqList 
 * @return 
 */
int Length(SqList_Static sqList) {
    return sqList.size;
}
/**
 * 返回元素e所在位置,返回值从1开始,到 <sqList.size> ,sqList中不存在元素e,则返回0
 * @param sqList list
 * @param e 元素e
 * @return 所在位置
 */
int LocateElem(SqList_Static sqList, ElementType e) {
    for (int i = 0; i < sqList.size; i++) {
        if (sqList.data[i] == e) return i + 1;
    }
    return 0;
}
/**
 * 删除
 * @param sqList
 * @param i
 * @param e 返回被删除元素的引用
 */
bool ListDelete(SqList_Static *sqList, int i, ElementType *e) {
    if (i < 1 || i > sqList->size) return false;
    *e = sqList->data[i - 1];
    for (int j = i; j < sqList->size; j++) {
        sqList->data[j - 1] = sqList->data[j];
    }
    sqList->size--;
    return true;
}
/**
 * 销毁线性表
 * @param sqList 线性表对象
 */
void DestroyList(SqList_Static *sqList) {
    free(sqList);
}
/**
 * 顺序表的逆置 
 * @param sqList 
 */
void Reverse(SqList_Static *sqList) {
    int i = 0;
    int j = sqList->size - 1;
    while (i < j) {
        int temp = sqList->data[i];
        sqList->data[i] = sqList->data[j];
        sqList->data[j] = temp;
        i++;
        j--;
    }
}
  • 笔记

<stdlib.h>头文件中有两个函数,int atoi(char *p)和char *itoa(int p),分别将装有整数的char数组转化为整数,和将整数按位数分解依次存入char数组中。

C语言中,free可以释放calloc, malloc, realloc动态分配的空间。
首先说明一下,释放的不是你定义的指针,而是你定义的指针指向的空间。
至于你定义的普通指针是不是可以通过free释放,这个要看情况。如果你定义的指针指向动态分配的地址空间,则可以使用free释放指针指向的这段空间;否则,就不能使用free释放指针指向的空间。下面举两个例子:
例1:char p = NULL; p = (char)malloc(1024); if (p != NULL) free§;
例2:char p = NULL; char buf[1024]; p = (char)buf; free§;
其中,例1是对的,例2是错误的。

值传递与址传递:ListDelete: *e = sqList->data[i - 1];

三元表达式: return (sqList.size == 0) ? true : false;

单链表

  • 结构体
typedef int ElemType;

typedef struct LNode {
    ElemType data;
    struct LNode *next;
} LNode, *LinkList;
  • 具体函数实现
/**
 * 带头结点-头插法建立单链表
 * @param linkList
 * @return
 */
LinkList ListHeadInsert(LinkList linkList) {
    FILE *file = fopen("E:\\DataStructure\\PostGraduate\\LinearList\\text", "r");
    linkList = (LinkList) malloc(sizeof(LinkList));
    linkList->next = NULL;
    LinkList temp;
    if (file == NULL) {
        printf("file open error!");
    } else {
        while (!feof(file)) {
            char ch[1024];
            fgets(ch, 1024, file);
            temp = (LinkList) malloc(sizeof(LinkList));
            temp->data = atoi(ch);
            printf("%d-", temp->data);
            temp->next = linkList->next;
            linkList->next = temp;
        }
    }
    return linkList;
}

/**
 * 带头结点-尾插法建立单链表
 * @param linkList
 * @return
 */
LinkList ListTailInsert(LinkList linkList) {
    FILE *file = fopen("E:\\DataStructure\\PostGraduate\\LinearList\\text", "r");
    linkList = (LinkList) malloc(sizeof(LinkList));
    linkList->next = NULL;
    LinkList temp, r = linkList;
    if (file == NULL) {
        printf("file open error!");
    } else {
        char ch[1024];
        while (!feof(file)) {
            fgets(ch, 1024, file);
            temp = (LinkList) malloc(sizeof(LinkList));
            temp->data = atoi(ch);
            r->next = temp;
            r = temp;
        }
        r->next = NULL;
    }
    return linkList;
}
/**
 * 输出链表
 * @param linkList
 */
void PrintLinkList(LinkList linkList) {
    if (linkList == NULL) {
        printf("linklist is null!");
        return;
    }
    LinkList p = linkList;
    while (p->next != NULL) {
        p = p->next;
        printf("%d ", p->data);
    }
}
/**
 * 按序号查找
 * 返回带有头节点的链表序列
 * @param linkList
 * @return
 */
LinkList GetElemFromI(LinkList linkList, int i) {
    LinkList p = linkList;
    if (i == 0) return linkList;
    if (i < 1) return NULL;
    while (p && i > 0) {
        p = p->next;
        i--;
    }
    LinkList res;
    res = (LinkList) malloc(sizeof(LinkList));
    res->next = p;
    return res;
}
/**
 * 按值查找
 * 返回带有头节点的链表序列
 * @param linkList
 * @return
 */
LinkList GetElemFromV(LinkList linkList, ElemType e) {
    LinkList p = linkList;
    while (p != NULL && p->data != e) {
        p=p->next;
    }
    LinkList res;
    res = (LinkList) malloc(sizeof(LinkList));
    res->next = p;
    return res;
}
/**
 * 插入操作(前插)
 * @param linkList
 * @param i 插入位置 - 从1开始
 * @param e 插入元素
 * @return
 */
LinkList InsertI(LinkList linkList, int i, ElemType e) {
    if (i <= 0) return NULL;
    LinkList p = linkList;
    while (i > 1) {
        p = p->next;
        i--;
    }
    LinkList t;
    t = (LinkList) malloc(sizeof(LinkList));
    t->data = e;
    t->next = p->next;
    p->next = t;
    return linkList;
}
/**
 * 按位删除
 * @param linkList
 * @param i 删除第i个元素
 * @return
 */
LinkList DeleteElemFromI(LinkList linkList, int i) {
    if (i <= 0) return NULL;
    LinkList p = linkList;
    while (p && i > 1) {
        p = p->next;
        i--;
    }
    if (p){
        LinkList q = p->next;
        p->next = q->next;
        free(q);
    }
    return linkList;
}
/**
 * 求表长
 * @param linkList
 * @return
 */
int LinkListLength(LinkList linkList) {
    int i = 0;
    LinkList p = linkList;
    p = p->next;
    while (p) {
        p = p->next;
        i++;
    }
    return i;
}
/**
 * 链表逆置
 * @param linkList
 * @return
 */
LinkList LinkListReverse(LinkList linkList) {
    LinkList p = linkList;
    LinkList r, temp;
    r = GetElemFromI(linkList, LinkListLength(linkList));
    r = r->next;
    while (p->next != r) {
        temp = p->next;
        p->next = temp->next;
        temp->next = r->next;
        r->next = temp;
    }
    return linkList;
}

对链表中间的一个链表对象使用free函数后,该对象后面的所有元素没有被free掉。同时记住让该对象的前一个对象的next指针置空。

  • 逆置

双链表

  • 结构体
typedef int ElemType;
typedef struct DNode {
    ElemType data;
    struct DNode *prior, *next;
} DNode, *DLinkList;

  • 结构体
#define MAXSIZE 100

typedef int ElemType;
typedef struct {
    ElemType data[MAXSIZE];
    int top;
} SqStack;
  • 函数实现
/**
 * 初始化
 * @param sqStack 
 */
void InitStack(SqStack *sqStack) {
    sqStack->top = -1;
}
/**
 * 判空
 * @param sqStack 
 * @return 
 */
bool StackEmpty(SqStack sqStack) {
    if (sqStack.top == -1) return true;
    else return false;
}
/**
 * 栈满:sqStack->top == MAXSIZE-1
 * @param sqStack 
 * @param e  保存并返回,以便 free
 * @return 
 */
bool Push(SqStack *sqStack, ElemType e) {
    if (sqStack->top == MAXSIZE - 1) return false;
    sqStack->data[++sqStack->top] = e;
    return true;
}
/**
 *
 * @param sqStack
 * @param e 保存并返回,以便 free
 * @return
 */
bool Pop(SqStack *sqStack, ElemType *e) {
    if (sqStack->top == -1) return false;
    *e = sqStack->data[sqStack->top];
    sqStack->top--;
}
/**
 * 读取栈顶元素
 * @param sqStack 
 * @param e 的返回值
 * @return 
 */
bool GetTop(SqStack sqStack, ElemType *e) {
    if (StackEmpty(sqStack)) return false;
    *e = sqStack.data[sqStack.top];
    return true;
}
void ClearStack(SqStack *sqStack) {
    sqStack->top = -1;
}

队列

  • 结构体
#define Maxsize 100

typedef int ElemType;
typedef struct {
    ElemType data[Maxsize];
    int front, rear;
} Queue;
  • 函数实现
void InitQueue(Queue *queue) {
    queue->front = queue->rear = 0;
}

bool QueueEmpty(Queue queue) {
    if (queue.rear == queue.front) return true;
    else return false;
}

bool EnQueue(Queue *queue, ElemType e) {
    if ((queue->rear + 1) % Maxsize == queue->front) return false;
    queue->data[queue->rear] = e;
    queue->rear = (queue->rear + 1) % Maxsize;
    return true;
}

bool DeQueue(Queue *queue, ElemType *e) {
    if (queue->front == queue->rear) return false;
    *e = queue->data[queue->front];
    queue->front = (queue->front + 1) % Maxsize;
    return true;
}

void GetHead(Queue queue, ElemType *e) {
    *e = queue.data[queue.front];
}

int GetSize(Queue queue) {
    return queue.rear - queue.front;
}


void ClearQueue(Queue *queue) {
    queue->front = queue->rear = 0;
}

栈的应用

  • 括号匹配
/**
 * 匹配
 * @param a 左括号
 * @param b 右括号
 * @return
 */
bool match(char a, char b) {
    if (a + 1 == b || a + 2 == b) return true;
    else return false;
}
/**
 * 括号匹配
 * @return
 */
bool BracketMatch(SqStack stack, const char str[]) {
    ElemType e;
    for (int i = 0; i < strlen(str); ++i) {
        switch (str[i]) {
            case '{':
            case '[':
            case '(':
                Push(&stack, str[i]);
                break;
            case '}':
            case ']':
            case ')':
                GetTop(stack, &e);
                if (match(e, str[i])) Pop(&stack, &e);
                else return false;
                break;
            default:
                break;
        }
    }
    if (StackEmpty(stack)) return true;
    else return false;
}
int main() {
    SqStack stack;
    InitStack(&stack);
    char str[] = "{[())]}";
    printf("match = %d\n", BracketMatch(stack, str) ? 1 : 0);
}

左括号与右括号,ASCII:“(”与“)”相差1,“[”与“]”,“{”与“}”相差2

  • 后缀表达式求值
/**
 * 读取char数组中的值
 * @param str
 * @param i 从第i个位置开始
 * @return double类型
 */
double ReadNumber(char str[], int *i) {
    double res = 0.0;
    int k = 0;//标记小数位数
    //处理整数部分
    while (str[*i] <= '9' && str[*i] >= '0') {
        res = res * 10 + (str[*i] - '0');
        (*i)++;
    }
    //处理小数部分
    if (str[*i] == '.') {
        (*i)++;
        while (str[*i] <= '9' && str[*i] >= '0') {
            res = res * 10 + (str[*i] - '0');
            (*i)++;
            k++;
        }
    }
    while (k != 0) {
        res = res / 10.0;
        k--;
    }
    return res;
}
/**
 * 后缀表达式求值
 * @param str 
 * @return 算下的结果
 */
double SuffixValue(char str[]) {
    SqStack stack;
    InitStack(&stack);
    int i = 0;
    ElemType x1, x2;
    while (str[i] != '#') {
        if (str[i] <= '9' && str[i] >= '0') {
            Push(&stack, ReadNumber(str, &i));
        } else if (str[i] == ' ') {
            i++;
        } else if (str[i] == '+') {
            Pop(&stack, &x2);
            Pop(&stack, &x1);
            Push(&stack, x1 + x2);
            i++;
        } else if (str[i] == '-') {
            Pop(&stack, &x2);
            Pop(&stack, &x1);
            Push(&stack, x1 - x2);
            i++;
        } else if (str[i] == '*') {
            Pop(&stack, &x2);
            Pop(&stack, &x1);
            Push(&stack, x1 * x2);
            i++;
        } else if (str[i] == '/') {
            Pop(&stack, &x2);
            Pop(&stack, &x1);
            Push(&stack, x1 / x2);
            i++;
        }
    }
    GetTop(stack, &x1);
    return x1;
}
int main() {
//    char str[] = "3 5 2 * - #";
    char str[] = "3 5 - 2 * #";
    printf("%f\n", SuffixValue(str));
}
  • 中缀表达式转变为后缀表达式
/**
 * 判断是否为操作符号
 * @param op
 * @return
 */
bool is_operation(char op) {
    switch (op) {
        case '+':
        case '-':
        case '*':
        case '/':
            return true;
        default:
            return false;
    }
}

/**
 * 返回操作符的优先级
 * @param op
 * @return
 */
int Priority(char op) {
    switch (op) {
        case '#':
            return -1;
        case '(':
            return 0;
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        default:
            return -1;
    }
}

/**
 * 转变体,输出即为后缀表达式
 * @param infix 中缀
 * @param suffix 后缀
 */
void Suffix(char infix[], char suffix[]) {
    SqStack stack;
    InitStack(&stack);
    ElemType e;
    int i = 0;
    while (infix[i] != '#') {
        if ((infix[i] <= '9' && infix[i] >= '0') || infix[i] == '.') {
            printf("%d ", infix[i] - '0');
        } else if (infix[i] == '(') {
            Push(&stack, infix[i]);
        } else if (infix[i] == ')') {
            GetTop(stack, &e);
            while (e != '(') {
                printf("%c ", e);
                Pop(&stack, &e);
                GetTop(stack, &e);
            }
            Pop(&stack, &e);
        } else if (is_operation(infix[i])) {
            GetTop(stack, &e);
            if (StackEmpty(stack)) {
                Push(&stack, infix[i]);
            } else if (e == '(') {
                Push(&stack, infix[i]);
            } else if (Priority(e) < Priority(infix[i])) {
                Push(&stack, infix[i]);
            } else {
                GetTop(stack, &e);
                while (Priority(e) >= Priority(infix[i]) || e == '(') {
                    printf("%c ", e);
                    Pop(&stack, &e);
                    GetTop(stack, &e);
                }
                Push(&stack, infix[i]);
            }
        }
        i++;
    }
    while (!StackEmpty(stack)) {
        GetTop(stack, &e);
        printf("%c ", e);
        Pop(&stack, &e);
    }
}

int main() {
    char infix[] = "4 * ( 2 + 1 ) #";
    char suffix[] = "4 * ( 2 + 1 ) #";
    Suffix(infix, suffix);
}

  • 双亲表示法
#define MAXSIZE 100

typedef char datatype;
typedef struct node {
    datatype data;
    int parent;
} temp;

typedef struct parent_tree {
    temp treeList[MAXSIZE];
    int length, root; //root:根节点的下标
};
  • 孩子表示法(数组)
#define DEGREE 3
#define MAXSIZE 20
typedef char datatype;

typedef struct child_array {
    datatype data;
    int child[DEGREE];
} child_array_tree;
child_array_tree tree[MAXSIZE];
int root;
int length;
  • 孩子表示法(链表)
#define MAXSIZE 50

typedef char datatype;
typedef struct child_node {
    int child;
    struct child_node *next;
} child_node, *child_point;
typedef struct {
    datatype data;
    child_point first_child;
} temp;
typedef struct {
    temp treeList[MAXSIZE];
    int length,root;
}child_tree;

二叉树

  • 结构体
typedef char datatype;
typedef struct bint_node {
    datatype data;
    struct bint_node *left, *right;
} bint_node, *bin_tree;
bin_tree root;
  • 函数实现
/**
 * 以先序遍历序列创建二叉树
 * 输入示例:abd#e##fg###c##
 * @return
 */
bin_tree createBinTree() {
    bin_tree tree;
    char ch;
    if ((ch = getchar()) == '#') {
        tree = NULL;
    } else {
        tree = (bin_tree) malloc(sizeof(bin_tree));
        tree->data = ch;
        printf("%c-", ch);
        tree->left = createBinTree();
        tree->right = createBinTree();
    }
    return tree;
}

/**
 * 先序遍历
 * 递归
 * @param tree
 */
void preOrder(bin_tree tree) {
    if (tree) {
        printf("%c ", tree->data);
        preOrder(tree->left);
        preOrder(tree->right);
    }
}

/**
 * 中序遍历
 * 递归
 * @param tree
 */
void inOrder(bin_tree tree) {
    if (tree) {
        inOrder(tree->left);
        printf("%c ", tree->data);
        inOrder(tree->right);
    }
}

/**
 * 后序遍历
 * 递归
 * @param tree
 */
void postOrder(bin_tree tree) {
    if (tree) {
        postOrder(tree->left);
        postOrder(tree->right);
        printf("%c ", tree->data);
    }
}
  • 非递归遍历(栈)
/**
 * 先序遍历
 * 非递归
 * @param tree
 */
void preOrder1(bin_tree tree) {
    binStack stack;
    stack.top = -1;
    while (tree || stack.top != -1) {
        if (tree) {
            printf("%c-", tree->data);
            Push(&stack, tree);
            tree = tree->left;
        } else {
            tree = Pop(&stack);
            tree = tree->right;
        }
    }
}

/**
 * 中序遍历
 * 非递归
 * @param tree
 */
void inOrder1(bin_tree tree) {
    binStack stack;
    stack.top = -1;
    while (tree || stack.top != -1) {
        if (tree) {
            binPush(&stack, tree);
            tree = tree->left;
        } else {
            tree = binPop(&stack);
            printf("%c-", tree->data);
            tree = tree->right;
        }
    }
}

/**
 * 后序遍历
 * 非递归
 * @param tree
 */
void postOrder1(bin_tree tree) {
    binStack stack;
    stack.top = 0;
    while (tree || stack.top != -1) {
        if (tree) {
            stack.data[stack.top] = tree;
            stack.tag[stack.top] = 0;
            stack.top++;
            tree = tree->left;
        } else {
            if (stack.tag[stack.top - 1] == 1) {
                stack.top--;
                tree = stack.data[stack.top];
                printf("%c-", tree->data);
                tree = NULL;
            } else {
                tree = stack.data[stack.top - 1];
                stack.tag[stack.top - 1] = 1;
                tree = tree->right;
            }
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KNM94d4x-1572164742740)(https://github.com/xieyipeng/MarkdownPic/blob/master/841446E1D1B4BFAEF26CA0290755E62D.JPG)])

  • 层次遍历(队列)
/**
 * 层次遍历
 * @param tree
 */
void levelOrder(bin_tree tree) {
    binQueue queue;
    init_binQueue(&queue);
    EnBinQueue(&queue, tree);
    bin_tree temp;
    while (queue.front != queue.rear) {
        DeBinQueue(&queue, &temp);
        printf("%c-",temp->data);
        if (temp->left!=NULL){
            EnBinQueue(&queue,temp->left);
        }
        if (temp->right!=NULL){
            EnBinQueue(&queue,temp->right);
        }
    }
}
  • 节点个数(递归)
/**
 * 返回二叉树的节点数目
 * @param tree
 */
int numOfNode(bin_tree tree) {
    if (tree == NULL) return 0;
    else return numOfNode(tree->left) + numOfNode(tree->right) + 1;
}
  • 等价(递归)
/**
 * 判断两颗二叉树是否等价
 * @param tree1 
 * @param tree2 
 * @return 
 */
int isEqual(bin_tree tree1, bin_tree tree2) {
    int t = 0;
    if (tree1 == NULL && tree2 == NULL) t = 1;
    else if (tree1 != NULL && tree2 != NULL)
        if (tree1->data == tree2->data)
            if (isEqual(tree1->left, tree2->left))
                t = isEqual(tree1->right, tree2->right);
    return (t);
}
  • 二叉树高度(递归)
/**
 * 返回树的深度
 * @param tree 
 * @return 
 */
int depth(bin_tree tree) {
    int h, lh, rh;
    if (tree == NULL) h = 0;
    else {
        lh = depth(tree->left);
        rh = depth(tree->right);
        if (lh >= rh) h = lh + 1;
        else h = rh + 1;
    }
    return h;
}

因本人节点从1开始计数,造成很多麻烦,代码中可能i,j之类的不能直接使用,需要稍微修改

  • 邻接矩阵法(结构体)
#define MAXSIZE 100
typedef char VertexType;
typedef int EdgeType;

typedef struct {
    VertexType vertex[MAXSIZE];
    EdgeType edge[MAXSIZE][MAXSIZE];
    int n, e;
} MGraph;
  • 建立图
/**
 * 邻接矩阵创建图
 * @param graph 边的数组从1开始
 * @param c 有向(1)或无向(0)图
 */
void create(MGraph *graph, int c) {
    graph->n = 0;
    graph->e = 0;
    int i, j;
    char ch[20];
    FILE *edge = fopen("E:\\DataStructure\\PostGraduate\\graph\\edge.txt", "r");
    FILE *vertex = fopen("E:\\DataStructure\\PostGraduate\\graph\\vertex.txt", "r");
    if (!edge || !vertex) {
        printf("file open error!!");
    } else {
        while (!feof(vertex)) {
            fscanf(vertex, "%d", &graph->vertex[graph->n]);
            graph->n++;
        }
        for (int m = 0; m <= graph->n; ++m) {
            for (int k = 0; k <= graph->n; ++k) {
                graph->edge[m][k] = FINITY;
            }
        }
        while (!feof(edge)) {
            fscanf(edge, "%d %d %s", &i, &j, ch);
            graph->edge[i][j] = atof(ch);
            if (c == 0) {
                graph->edge[j][i] = atof(ch);
            }
            graph->e++;
        }
    }
}

fscanf读到空格或者回车时会把空格或回车转化为/0(字符串结束符)而fgets函数则把空格(回车在下文解释)作为字符接收。

  • 深度优先遍历
bool visited[MAXSIZE];

void dfs(MGraph graph, int i) {
    printf("%d->", graph.vertex[i - 1]); //输出序列
    visited[i] = true;
    for (int j = 1; j <= graph.n; ++j) {
        if (!visited[j] && graph.edge[i][j] != FINITY) {
            dfs(graph, j);
        }
    }
}

/**
 * 标记位从0开始,实际节点编号从1开始
 * @param graph
 */
void dfsTraverse(MGraph graph) {
    for (int i = 1; i <= graph.n; ++i) {
        visited[i] = false;
    }
    for (int i = 1; i <= graph.n; ++i) { //用于有多个图
        if (!visited[i]) dfs(graph, i);
    }
}
  • 广度优先遍历
void bfs(MGraph graph, int i) {
    if (!visited[i]) {
        printf("%d->", graph.vertex[i - 1]);
        visited[i] = true;
    }
    int temp[MAXSIZE];
    int rear = 0, front = 0;
    for (int j = 1; j <= graph.n; ++j) {
        if (!visited[j] && graph.edge[i][j] != FINITY) {
            //访问并入队
            printf("%d->", graph.vertex[j - 1]);
            visited[j] = true;
            temp[rear] = j;
            rear++;
        }
    }
    while (rear != front) {
        bfs(graph, temp[front]);
        front++;
    }
}

/**
 * bfs广度优先遍历
 * @param graph
 * @return 连通分量的个数
 */
int bfsTraverse(MGraph graph) {
    int count = 0;
    for (int i = 1; i <= graph.n; ++i) {
        visited[i] = false;
    }
    for (int j = 1; j <= graph.n; ++j) {
        dfs(graph, j);
        count++;
    }
    return count;
}
  • 最小生成树(prim)
/**
 * 最小生成树prim算法
 * @param graph
 */
void prim(MGraph graph) {
    edge tree[graph.n - 1];
    edge temp;
    EdgeType min, d;
    int s = 0, v;
    for (int i = 1; i <= graph.n; ++i) {
        tree[i - 1].begin = 1;
        tree[i - 1].end = i + 1;
        tree[i - 1].length = graph.edge[1][i + 1];
    }
    for (int k = 0; k <= graph.n - 3; ++k) {
        min = tree[k].length;
        s = k;
        for (int j = k + 1; j <= graph.n - 2; ++j) {
            if (tree[j].length < min && tree[j].length != FINITY) {
                min = tree[j].length;
                s = j;
            }
        }
        v = tree[s].end;
        temp = tree[s];
        tree[s] = tree[k];
        tree[k] = temp;
        for (int j = k + 1; j <= graph.n - 2; ++j) {
            d = graph.edge[v][tree[j].end];
            if (d < tree[j].length) {
                tree[j].length = d;
                tree[j].begin = v;
            }
        }
    }
    printf("the minimum cost spanning tree is :\n");
    for (int j = 0; j <= graph.n - 2; ++j) {
        printf("%d---%d %.2f \n", tree[j].begin, tree[j].end, tree[j].length);
    }
    printf("the root is %d\n", graph.vertex[0]);
}
  • 最小生成树(kruskal)
/**
 * 对边排序
 * @param edges 
 * @param left 
 * @param right 
 */
void sort(edge *edges, int left, int right) {
    int i = 0, j = 0;
    edge x;
    if (left < right) {
        i = left;
        j = right;
        x = edges[i];
        while (i < j) {
            while (i < j && x.length < edges[j].length) j--;
            if (i < j) edges[i++] = edges[j];
            while (i < j && x.length > edges[i].length) i++;
            if (i < j) edges[j--] = edges[i];
        }
        edges[i] = x;
        sort(edges, left, i - 1);
        sort(edges, i + 1, right);
    }
}

void GetEdge(MGraph graph, edge edges[]) {
    int count = 0;
    for (int i = 0; i <= graph.n; ++i) {
        for (int j = 0; j < i; ++j) {
            if (graph.edge[i][j] != 0 && graph.edge[i][j] != FINITY) {
                edges[count].begin = i;
                edges[count].end = j;
                edges[count].length = graph.edge[i][j];
                count++;
            }
        }
    }
}

/**
 * kruskal算法
 * @param graph
 */
void kruskal(MGraph graph) {
    int k = 0;
    int cnvx[graph.n];
    edge edges[graph.e];
    edge tree[graph.n - 1];
    GetEdge(graph, edges);
    sort(edges, 0, graph.e - 1);
    for (int j = 0; j < graph.n; ++j) {//初始化连通分量
        cnvx[j] = j;
    }
    for (int i = 0; i < graph.n - 1; ++i) {
        while (cnvx[edges[k].begin - 1] == cnvx[edges[k].end - 1]) k++;
        tree[i] = edges[k];
        int temp = cnvx[edges[k].end - 1];
        for (int j = 0; j < graph.n; ++j) {
            if (cnvx[j] == temp) {
                cnvx[j] = cnvx[edges[k].begin - 1];
            }
        }
        k++;
    }
    printf("the minimum cost spanning tree is :\n");
    for (int l = 0; l < graph.n - 1; ++l) {
        printf("%d---%d %.2f \n", tree[l].begin, tree[l].end, tree[l].length);
    }
}

  • 单源最短路径算法(dijkstra)
void print_pgd(MGraph graph, int path[], float dist[]) {
    for (int j = 0; j < graph.n; ++j) {
        path[j] = path[j] - 1;
    }
    int st[graph.n], pre, top = -1;
    for (int i = 0; i < graph.n; ++i) {
        printf("\nDistance: %.2f , path: ", dist[i]);
        st[++top] = i;
        pre = path[i];
        while (pre != -1) {
            st[++top] = pre;
            pre = path[pre];
        }
        while (top > 0) {
            printf("%2d", (st[top--] + 1));
        }
    }
}

/**
 * dijkstra算法求单源最短路径
 * @param graph
 * @param v0
 */
void dijkstra(MGraph graph, int v0) {
    float min = 0;
    int v = 0;
    float dist[graph.n];
    int path[graph.n];
    bool final[graph.n];
    for (int i = 0; i < graph.n; ++i) {
        final[i] = false;
        dist[i] = graph.edge[v0][i + 1];
        if (dist[i] < FINITY && dist[i] != 0) path[i] = v0;
        else path[i] = 0;
    }
    final[v0 - 1] = true;
    dist[v0 - 1] = 0;
    for (int i = 2; i <= graph.n; ++i) {
        //找到dist内最小距离
        min = FINITY;
        for (int k = 0; k < graph.n; ++k) {
            if (!final[k] && dist[k] < min) {
                v = k;
                min = dist[k];
            }
        }
        printf("%d---%.2f\n", v, min);
        if (min == FINITY) {
            return;
        } else {
            final[v] = true;
        }
        final[v] = true;
        //修改dist和path数组
        for (int k = 0; k < graph.n; ++k) {
            if (!final[k] && (min + graph.edge[v + 1][k + 1] < dist[k])) {
                dist[k] = min + graph.edge[v + 1][k + 1];
                path[k] = v + 1;
            }
        }
    }
    print_pgd(graph, path, dist);
}

  • Floyd算法求最短路径
/**
 * floyd算法
 * @param graph
 */
void floyd(MGraph graph) {
    int dist[graph.n][graph.n];
    int path[graph.n][graph.n];
    for (int i = 0; i < graph.n; ++i) {
        for (int j = 0; j < graph.n; ++j) {
            dist[i][j] = graph.edge[i][j];
            if (i != j && dist[i][j] < FINITY) {
                path[i][j] = i;
            } else {
                path[i][j] = -1;
            }
        }
    }
    for (int k = 0; k < graph.n; ++k) {
        for (int i = 0; i < graph.n; ++i) {
            for (int j = 0; j < graph.n; ++j) {
                if (dist[i][j] > (dist[i][k] + dist[k][j])) {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    path[i][k] = k;
                }
            }
        }
    }
}

查找

  • kmp算法
/**
 * next数组
 * @param p
 * @param next
 */
void getNext(seqString p, int next[]) {
    next[0] = -1;
    int i = 0;
    int j = -1;
    while (i < p.length) {
        if (j == -1 || p.str[i] == p.str[j]) {
            ++i;
            ++j;
            next[i] = j;
        } else {
            j = next[j];
        }
    }
}

/**
 * 模式匹配kmp算法
 */
int kmp(seqString t, seqString p, int next[]) {
    int i = 0;
    int j = 0;
    while (i < t.length && j < p.length) {
        if (j==-1||t.str[i]==p.str[j]){
            i++;
            j++;
        } else{
            j=next[j];
        }
    }
    if (j==p.length) return (i-p.length);
    else return (-1);
}

排序

  • 插入排序

strlen只可以用来测量char*字符串的长度,求数组长度(比如int a[])要用sizeof(a)/sizeof(int)

/**
 * 直接插入排序
 * @param a
 * @param n
 */
void insertSort(ElemType a[], int n) {
    int sentry = 0;
    for (int i = 1; i < n; ++i) {
        int j = i - 1;
        sentry = a[i];
        while (sentry < a[j]) {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = sentry;
    }
}
/**
 * 折半查找
 * @param a
 * @param n
 */
void binary(ElemType a[], int n) {
    int sentry = 0;
    int low = 0, high = 0;
    for (int i = 1; i < n; ++i) {
        sentry = a[i];
        low = 0;
        high = i;
        //查找
        while (low <= high) {
            int mid = (low + high) / 2;
            if (sentry < a[mid]) high = mid - 1;
            else low = mid + 1;
        }
        //移动
        for (int j = i - 1; j >= high + 1; --j) {
            a[j + 1] = a[j];
        }
        a[low] = sentry;
    }
}
/**
 * 希尔排序
 * @param a
 * @param n
 */
void shellSort(ElemType a[], int n) {
    int d = n / 2;
    int sentry;
    while (d >= 1) {
        for (int i = d; i < n; ++i) {
            sentry = a[i];
            int j = i - d;
            while (j >= 0 && sentry < a[j]) {
                a[j + d] = a[j];
                j = j - d;
            }
            a[j + d] = sentry;
        }
        print_sort(a,n);
        d = d / 2;
    }
}
  • 希尔排序

  • 交换排序

/**
 * 冒泡排序
 * @param a
 * @param n
 */
void bubbling(ElemType a[], int n) {
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if (a[i] > a[j]) {
                int temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
    }
}
/**
 * 快速排序
 * @param a
 * @param low
 * @param high
 */
void quick(ElemType a[], int low, int high) {
    if (low < high) {
        int i = low;
        int j = high;
        int sentry = a[low];
        while (i != j) {
            while (sentry < a[j] && i < j) j--;
            if (i < j) {
                a[i] = a[j];
                i++;
            }
            while (sentry > a[i] && i < j) i++;
            if (i < j) {
                a[j] = a[i];
                j--;
            }
        }
        a[i] = sentry;
        quick(a, low, i - 1);
        quick(a, i + 1, high);
    }
}
  • 选择排序
/**
 * 选择排序
 * @param a
 * @param i
 */
void select(ElemType a[], int n) {
    for (int j = 0; j < n - 1; ++j) {
        int min = j;
        for (int i = j+1; i < n; ++i) {
            if (a[i]<a[min]) min=i;
        }
        if (min!=j){
            ElemType temp=a[j];
            a[j]=a[min];
            a[min]=temp;
        }
    }
}
数据结构1800题1. 算法的计算量的大小称为计算的( )。【北京邮电大学2000 二、3 (20/8分)】 A.效率 B. 复杂性 C. 现实性 D. 难度 2. 算法的时间复杂度取决于( )【中科院计算所 1998 二、1 (2分)】 A.问题的规模 B. 待处理数据的初态 C. A和B 3.计算机算法指的是(1),它必须具备(2) 这三个特性。 (1) A.计算方法 B. 排序方法 C. 解决问题的步骤序列 D. 调度方法 (2) A.可执行性、可移植性、可扩充性 B. 可执行性、确定性、有穷性 C. 确定性、有穷性、稳定性 D. 易读性、稳定性、安全性 【南京理工大学 1999 一、1(2分) 【武汉交通科技大学 1996 一、1( 4分)】 4.一个算法应该是( )。【中山大学 1998 二、1(2分)】 A.程序 B.问题求解步骤的描述 C.要满足五个基本特性 D.A和C. 5. 下面关于算法说法错误的是( )【南京理工大学 2000 一、1(1.5分)】 A.算法最终必须由计算机程序实现 B.为解决某问题的算法同为该问题编写的程序含义是相同的 C. 算法的可行性是指指令不能有二义性 D. 以上几个都是错误的 6. 下面说法错误的是( )【南京理工大学 2000 一、2 (1.5分)】 (1)算法原地工作的含义是指不需要任何额外的辅助空间 (2)在相同的规模n下,复杂度O(n)的算法在时间上总是优于复杂度O(2n)的算法 (3)所谓时间复杂度是指最坏情况下,估算算法执行时间的一个上界 (4)同一个算法,实现语言的级别越高,执行效率就越低 A.(1) B.(1),(2) C.(1),(4) D.(3) 7.从逻辑上可以把数据结构分为( )两大类。【武汉交通科技大学 1996 一 、4(2分)】 A.动态结构、静态结构 B.顺序结构、链式结构 C.线性结构、非线性结构 D.初等结构、构造型结构
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值