考研数据结构

线性表

顺序表

  • 结构体
#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;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值