数据结构与算法

数据结构与算法

核心逻辑

  1. 定义
  2. 初始化创建数据结构
  3. 增加
  4. 删除
  5. 打印
  6. 可能会有判断空/满情况

链表

单链表

#include<stdlib.h>
typedef struct list{
	int data;
	struct list *next;
}node;

node* creatlisthead()
{
	node* head=(node*)malloc(sizeof(node));
	head->next=NULL;
	return head;
}
void headsert(node*head,int data)
{
	node*p=(node*)malloc(sizeof(node));
	
	p->data=data;
	p->next=head->next;
	head->next=p;
}
void tailsert(node*head,int data)
{
		node*p=(node*)malloc(sizeof(node));
		p->data=data;
		p->next=NULL;
		
		node*list=head;
		while(list->next)
		{
			list=list->next;
		}
		list->next=p;
}
void deletelist(node*head,int data)
{
	node* list=head;
	while(list->next)
	{
		if(list->next->data==data)
		{
			list->next=list->next->next;
			return ;
		}
		list=list->next;
	}
	
}

void print(node*head)
{
	node* list=head->next;
	while(list)
	{
		printf("%d",list->data);
		list=list->next;
	}
}
int main()
{
	node *head=creatlisthead();
	headsert(head,1);
	headsert(head,2);
	headsert(head,3);
	
	deletelist(head,3);

	tailsert(head,4);
	tailsert(head,5);
		deletelist(head,5);
	tailsert(head,6);
		deletelist(head,6);
	print(head);
	return 0;
}`

循环链表

#include<stdlib.h>

typedef struct list{
	int data;
	struct list *next;
}node;

node* creatlisthead()
{
	node* head=(node*)malloc(sizeof(node));
	head->next=head;
	return head;
}
void headsert(node*head,int data)
{
	node*p=(node*)malloc(sizeof(node));
	
	p->data=data;
	p->next=head->next;
	head->next=p;
}
void tailsert(node*head,int data)
{
		node*p=(node*)malloc(sizeof(node));
		p->data=data;
		node *list=head;
		while(list->next!=head)
		{
			list=list->next;
		}
		list->next=p;
		p->next=head;
}
void deletelist(node*head,int data)
{
	node* list=head;
	while(list->next!=head)
	{
		if(list->next->data==data)
		{
			list->next=list->next->next;
			return ;
		}
		list=list->next;
	}
}

void print(node*head)
{
	node* list=head;
	while(list->next!=head)
	{
		printf("%d->",list->next->data);
		list=list->next;
	}
	printf("NULL");
}
int main()
{
	node *head=creatlisthead();
	headsert(head,1);
	headsert(head,2);
	headsert(head,3);
	
	deletelist(head,3);

	tailsert(head,4);
	tailsert(head,5);
	deletelist(head,5);
	tailsert(head,6);
	deletelist(head,6);
	print(head);
	return 0;
}`

双向链表

#include<stdlib.h>
 typedef struct node{
 	int data;
 	struct node*pre;
 	struct node*next;
 }Node;
 
 Node* creathead()
 {
 	Node*head=(Node*)malloc(sizeof(Node));
 	head->pre=NULL;
 	head->next=NULL;
 	return head;
 }
 
 void headsert(Node*head,int data)
 {
 	Node*p=(Node*)malloc(sizeof(Node));
 	p->data=data;
	if(head->next)
 	{
	 		p->next=head->next;
		  	p->pre=head;
		  	head->next->pre=p;
		  	head->next=p;
	 }else{
//	 	判断是否为空
	 	p->next=head->next;
	 	p->pre=head;
	 	head->next=p;
	 }
 	
 }
 void tailsert(Node*head,int data)
 {
 	Node*p=(Node*)malloc(sizeof(Node));
 	p->data=data;
 	p->next=NULL;
 	Node*q=head;
 	while(q->next)
 	{
	 	q=q->next;
	 }
	 p->pre=q;
	 q->next=p;
	 
 }
 void del(Node*head,int data)
 {
 	Node*p=head;
 	while(p->next)
 	{
	 	if(p->data==data)
	 	{
		 p->pre->next=p->next;
		 p->next->pre=p->pre;
		 return;
		 }
		 p=p->next;
	 }
	 p->pre->next=NULL;
 }
 void print(Node*head)
 {
 	Node*list=head->next;
 	while(list)
 	{
	 	printf("%d->",list->data);
	 	list=list->next;
	 }
	 
	 printf("NULL\n");
 }
int main()
{
	Node*head=creathead();
	headsert(head,1);
	headsert(head,2);
	headsert(head,3);
	del(head,3);
	print(head);
	tailsert(head,4);
	tailsert(head,5);
	tailsert(head,6);
    del(head,6);
	print(head);
	return 0;
}`

双向循环链表

#include<stdlib.h>
 typedef struct node{
 	int data;
 	struct node*pre;
 	struct node*next;
 }Node;
 
 Node* creathead()
 {
 	Node*head=(Node*)malloc(sizeof(Node));
 	head->pre=head;//注意指向自己
 	head->next=head;
 	return head;
 }
 
 void headsert(Node*head,int data)
 {
 	Node*p=(Node*)malloc(sizeof(Node));
 	p->data=data;
	if(head->next)
 	{
	 		p->next=head->next;
		  	p->pre=head;
		  	head->next->pre=p;
		  	head->next=p;
	 }else{
//	 	判断是否为空
	 p->pre=head;
	 head->next=p;
	 p->next=head;
	 head->pre=p;
	 }
 	
 }
 void tailsert(Node*head,int data)
 {
 	Node*p=(Node*)malloc(sizeof(Node));
 	p->data=data;
 
 	Node*q=head;
 	while(q->next!=head)
 	{
	 	q=q->next;
	}
	 p->pre=q;
	 p->next=head;
	 q->next=p;
	 head->pre=p;
	 
 }
 void del(Node*head,int data)
 {
 	Node*p=head;
 	while(p->next!=head)
 	{
	 	if(p->data==data)
	 	{
		 p->pre->next=p->next;
		 p->next->pre=p->pre;
		 return;
		 }
		 p=p->next;
	 }
	p->pre->next=head;
	head->pre=p->pre;
 }
 void print(Node*head)
 {
 	Node*list=head->next;
 	while(list!=head)
 	{
	 	printf("%d->",list->data);
	 	list=list->next;
	 }
	 printf("NULL\n");
 }
int main()
{
	Node*head=creathead();
	headsert(head,1);
	headsert(head,2);
	headsert(head,3);
	del(head,3);
	print(head);
	tailsert(head,4);
	tailsert(head,5);
	tailsert(head,6);
    del(head,6);
	print(head);
	return 0;
}`

#include<stdlib.h>

typedef struct node{
	int data;
	struct node*next;	
}Node;
Node*creatstack()
{
	Node*head=(Node*)malloc(sizeof(Node));
	head->next=NULL;
	return head;
}
void push(Node*head,int data)//采用头插法,因为出栈只能从头出,于是链表头为栈顶
{
		Node*p=(Node*)malloc(sizeof(Node));
		p->data=data;
		p->next=head->next;
		head->next=p;
		
}
int isempty(Node*head)
{
	if(head->next)
	return 0;
	return 1;
}
void pop(Node*head)
{
	if(head->next)
	{
	 Node*p=head->next;
  	 int a=p->data;
		printf("pop=%d\n",a);
		head->next=p->next;
		head=p;//为什么有这一步
//		free(p);
		
	}else{
	return;
	}
}
void print(Node*head)
{
Node*p=head->next;
while(p)
{
	printf("%d->",p->data);
	p=p->next;
}
printf("NULL\n");
}
int main()
{
	Node*head=creatstack();
	push(head,1);
	
		push(head,2);
			push(head,3);
				push(head,4);
				print(head);
	printf("poping\n");			
	pop(head);
	print(head);
	pop(head);
	print(head);
	pop(head);
	print(head);
	
	
	return 0;
}`

队列

一般

#include<stdlib.h>

typedef struct node{
	int data;
	struct node*next;
	
}Node;
Node*creatqueue()
{
	Node*head=(Node*)malloc(sizeof(Node));
	head->next=NULL;
	return head;
}
void enqueue(Node*head,int data)//尾插法创建,因为头部要出队,头部为先进队的,所以,尾插法处理后进队的
{
	Node*p=(Node*)malloc(sizeof(Node));
	p->data=data;
	Node*q=head;
	while(q->next)
	{
		q=q->next;
	}
	p->next=q->next;
	q->next=p;
}
void popqueue(Node*head)
{
	if(head->next)
	{
		Node*p=head->next;
		printf("pop=%d\n",p->data);
		head->next=p->next;
		head=p;
	}else{
		printf("NULL");
	}
}
void print(Node*head)
{
	Node*p=head->next;
	while(p)
	{
		printf("%d->",p->data);
		p=p->next;
	}
	printf("NULL");
}
int main()
{
	Node*head=creatqueue();
	enqueue(head,1);
		enqueue(head,2);
			enqueue(head,3);
	print(head);
	popqueue(head);
	print(head);
	popqueue(head);
	print(head);	
		popqueue(head);
		print(head);
	return 0;
}`

循环队列

  1. 循环队列的长度表示 len=(head->rear-head->front+Max)%Max;
  2. rear及front的表示 head->front=(head->front+1)%Max;
  3. 取余时,小数取大数=小数,大数取小数=大数-小数,两数等为0
#include<stdlib.h>
#define Max 5
 typedef struct node{
 	int data[Max];
 	int front;
 	int rear;
 }Que;
 
 Que* creatqueue()
 {
 	Que* head=(Que*)malloc(sizeof(Que));
 	head->front=head->rear=0;
 	return head;
 }
 int isfull(Que*head)
 {
 	if((head->rear+1)%Max==head->front)//判断队满
 	return 1;
 	return 0;
 }
 int isempty(Que*head)
 {
 	if(head->front==head->rear)//判断队空
 	return 1;
 	return 0;
 }
 void enqueue(Que*head,int data)
 {
 	if(isfull(head))
 	{
	 	;
	 }else{
	 	head->data[head->rear]=data;
	 	head->rear=(head->rear+1)%Max;
	 	//rear 处不放值
	 }
 	
 }
 void delqueue(Que*head)
 {
 	if(isempty(head))
 	{
	 	;
	 }else{
	 	printf("del=%d\n",head->data[head->front]);
	 	head->front=(head->front+1)%Max;
	 	//front 处有值
	 }
 }
 void print(Que*head)
 {
 	int len=(head->rear-head->front+Max)%Max;
 	int index=head->front;
 	for(int i=0;i<len;i++)
 	{
	 	printf("%d->",head->data[index]);
	 	index++;
	 }
	 printf("NULL");
 }
int main()
{
	
	Que*q=creatqueue();
	enqueue(q,1);
	enqueue(q,2);	
	enqueue(q,3);
			enqueue(q,4);
			print(q);
			delqueue(q);
			print(q);
	return 0;
}`

字符串暴力匹配

  1. 初始化字符串(数据域,字符串长度)

  2. 暴力匹配

    /**
     * File Name: ForceMatch.c
     * Author: tyrantlucifer
     * E-mail: tyrantlucifer@gmail.com
     * Blog: https://tyrantlucifer.com
     */
    #include <stdio.h>
    #include <stdlib.h>
    
    /**
     * define struct of string
     */
    typedef struct String {
        char* data;
        int len;
    } String;
    
    /**
     * init string
     * @return the pointer of string
     */
    String* initString() {
        String* s = (String*)malloc(sizeof(String));
        s->data = NULL;
        s->len = 0;
        return s;
    }
    
    /**
     * assign value to a string
     * @param s the pointer of string
     * @param data the value you want to assign
     */
    void stringAssign(String* s, char* data) {
        if (s->data) {
            free(s->data);
        }
        int len = 0;
        char* temp = data;
        while (*temp) {//为什么不是temp
            len++;
            temp++;
        }
        if (len == 0) {
            s->data = NULL;
            s->len = 0;
        } else {
            temp = data;
            s->len = len;
            s->data = (char*)malloc(sizeof(char) * (len + 1));//指针使用要开辟空间
            for (int i = 0; i < len; i++, temp++) {
                s->data[i] = *temp;
            }
        }
    }
    
    /**
     * print string
     * @param s the pointer of string
     */
    void printString(String* s) {
        for (int i = 0; i < s->len; i++) {
            printf(i == 0 ? "%c " : "-> %c ", s->data[i]);
        }
        printf("\n");
    }
    
    /**
     * force match
     * @param master the pointer of master string
     * @param sub the pointer of sub string
     */
    void forceMatch(String* master, String* sub) {
        int i = 0;
        int j = 0;
        while (i < master->len && j < sub->len) {
            if (master->data[i] == sub->data[j]) {
                i++;
                j++;
            } else {
                i = i - j + 1;
                j = 0;
            }
        }
        if (j == sub->len) {
            printf("force match success.\n");
        } else {
            printf("force match fail.\n");
        }
    }
    
    /**
     * main function
     * @param argc the num of args
     * @param argv the array of args
     * @return null
     */
    int main(int argc, char* argv[]) {
        String* s = initString();
        String* s1 = initString();
        stringAssign(s, argv[1]);
        stringAssign(s1, argv[2]);
        printString(s);
        printString(s1);
        forceMatch(s, s1);
        return 0;
    }
    

kmp算法

/**
 * File Name: KMPMatch.c
 * Author: tyrantlucifer
 * E-mail: tyrantlucifer@gmail.com
 * Blog: https://tyrantlucifer.com
 */
#include <stdio.h>
#include <stdlib.h>

/**
 * define struct of string
 */
typedef struct String {
    char* data;
    int len;
} String;

/**
 * init string
 * @return the pointer of string
 */
String* initString() {
    String* s = (String*)malloc(sizeof(String));
    s->data = NULL;
    s->len = 0;
    return s;
}

/**
 * assign value to a string
 * @param s the pointer of string
 * @param data the data you want to assign
 */
void stringAssign(String* s, char* data) {
    if (s->data) {
        free(s->data);
    }
    int len = 0;
    char* temp = data;
    while (*temp) {
        len++;
        temp++;
    }
    if (len == 0) {
        s->data = NULL;
        s->len = 0;
    } else {
        temp = data;
        s->len = len;
        s->data = (char*)malloc(sizeof(char) * (len + 1));
        for (int i = 0; i < len; i++, temp++) {
            s->data[i] = *temp;
        }
    }
}

/**
 * print string
 * @param s the pointer of string
 */
void printString(String* s) {
    for (int i = 0; i < s->len; i++) {
        printf(i == 0 ? "%c " : "-> %c ", s->data[i]);
    }
    printf("\n");
}

/**
 * get next array for a string
 * @param s the pointer of string
 * @return the next array pointer
 */
int* getNext(String* s) {
    int* next = (int*)malloc(sizeof(int) * s->len);
    int i = 0;
    int j = -1;
    next[i] = j;
    while (i < s->len - 1) {
        if (j == -1 || s->data[i] == s->data[j]) {
            i++;
            j++;
            next[i] = j;
        } else {
            j = next[j];
        }
    }
    return next;
}

/**
 * print next array
 * @param next the pointer of array
 * @param len the len of next array
 */
void printNext(int* next, int len) {
    for (int i = 0; i < len; i++) {
        printf(i == 0 ? "%d " : "-> %d ", next[i] + 1);
    }
    printf("\n");
}

/**
 * kmp match
 * @param master the pointer of master string 
 * @param sub the pointer of sub string
 * @param next the next array pointer array
 */
void kmpMatch(String* master, String* sub, int* next) {
    int i = 0;
    int j = 0;
    while (i < master->len && j < sub->len) {
        if (j == -1 || master->data[i] == sub->data[j]) {
            i++;
            j++;
        } else {
            j = next[j];
        }
    }
    if (j == sub->len) {
        printf("kmp match success.\n");
    } else {
        printf("kmp match fail.\n");
    }
}

/**
 * main function
 * @param argc the num of args
 * @param argv the array of args
 * @return null
 */
int main(int argc, char* argv[]) {
    String* s = initString();
    String* s1 = initString();
    stringAssign(s, argv[1]);
    printString(s);
    stringAssign(s1, argv[2]);
    printString(s1);
    int* next = getNext(s1);
    printNext(next, s1->len);
    kmpMatch(s, s1, next);
    return 0;
}/**
 * File Name: KMPMatch.cpp
 * Author: tyrantlucifer
 * E-mail: tyrantlucifer@gmail.com
 * Blog: https://tyrantlucifer.com
 */
#include <stdio.h>
#include <stdlib.h>

/**
 * define struct of string
 */
typedef struct String {
    char* data;
    int len;
} String;

/**
 * init string
 * @return the pointer of string
 */
String* initString() {
    String* s = (String*)malloc(sizeof(String));
    s->data = NULL;
    s->len = 0;
    return s;
}

/**
 * assign value to a string
 * @param s the pointer of string
 * @param data the data you want to assign
 */
void stringAssign(String* s, char* data) {
    if (s->data) {
        free(s->data);
    }
    int len = 0;
    char* temp = data;
    while (*temp) {
        len++;
        temp++;
    }
    if (len == 0) {
        s->data = NULL;
        s->len = 0;
    } else {
        temp = data;
        s->len = len;
        s->data = (char*)malloc(sizeof(char) * (len + 1));
        for (int i = 0; i < len; i++, temp++) {
            s->data[i] = *temp;
        }
    }
}

/**
 * print string
 * @param s the pointer of string
 */
void printString(String* s) {
    for (int i = 0; i < s->len; i++) {
        printf(i == 0 ? "%c " : "-> %c ", s->data[i]);
    }
    printf("\n");
}

/**
 * get next array for a string
 * @param s the pointer of string
 * @return the next array pointer
 */
int* getNext(String* s) {
    int* next = (int*)malloc(sizeof(int) * s->len);
    int i = 0;
    int j = -1;
    next[i] = j;
    while (i < s->len - 1) {
        if (j == -1 || s->data[i] == s->data[j]) {
            i++;
            j++;
            next[i] = j;
        } else {
            j = next[j];
        }
    }
    return next;
}

/**
 * print next array
 * @param next the pointer of array
 * @param len the len of next array
 */
void printNext(int* next, int len) {
    for (int i = 0; i < len; i++) {
        printf(i == 0 ? "%d " : "-> %d ", next[i] + 1);
    }
    printf("\n");
}

/**
 * kmp match
 * @param master the pointer of master string 
 * @param sub the pointer of sub string
 * @param next the next array pointer array
 */
void kmpMatch(String* master, String* sub, int* next) {
    int i = 0;
    int j = 0;
    while (i < master->len && j < sub->len) {
        if (j == -1 || master->data[i] == sub->data[j]) {
            i++;
            j++;
        } else {
            j = next[j];
        }
    }
    if (j == sub->len) {
        printf("kmp match success.\n");
    } else {
        printf("kmp match fail.\n");
    }
}

/**
 * main function
 * @param argc the num of args
 * @param argv the array of args
 * @return null
 */
int main(int argc, char* argv[]) {
    String* s = initString();
    String* s1 = initString();
    stringAssign(s, argv[1]);
    printString(s);
    stringAssign(s1, argv[2]);
    printString(s1);
    int* next = getNext(s1);
    printNext(next, s1->len);
    kmpMatch(s, s1, next);
    return 0;
}

二叉树

基础

创建与遍历-左右孩子表示法

``

/*************************************************************************
* File Name: tree.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Sun 09 May 2021 08:47:34 PM CST
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
    char data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
}TreeNode;

void createTree(TreeNode** T, char* data, int* index) {
    char ch;
    ch = data[*index];
    *index += 1;
    if (ch == '#') {
        // 此时为空节点
        *T = NULL;
    }
    else {
        // 此时不为空
        *T = (TreeNode*)malloc(sizeof(TreeNode));//指针使用要么开辟空间,要么赋值(地址)
        (*T) -> data = ch;
        // 创建左子树,逻辑一致,进行递归
        createTree(&((*T)->lchild), data, index);
        // 创建右子树,逻辑一致,进行递归
        createTree(&((*T)->rchild), data, index);
    }
}

void preOrder(TreeNode* T) {
    if (T == NULL) {
        return;
    }
    else {
        // 先办事
        printf("%c ", T->data);
        // 处理左孩子
        preOrder(T->lchild);
        // 处理右孩子
        preOrder(T->rchild);
    }
}

void inOrder(TreeNode* T) {
    if (T == NULL) {
        return;
    }
    else {
        // 处理左孩子
        inOrder(T->lchild);
        // 中办事
        printf("%c ", T->data);
        // 处理右孩子
        inOrder(T->rchild);
    }
}

void postOrder(TreeNode* T) {
    if (T == NULL) {
        return;
    }
    else {
        // 处理左孩子
        postOrder(T->lchild);
        // 处理右孩子
        postOrder(T->rchild);
        // 后办事
        printf("%c ", T->data);
    }
}


int main(int argc, char* argv[]) {
    TreeNode* T;
    int index = 0;
    createTree(&T, argv[1], &index);
    preOrder(T);
    printf("\n");
    inOrder(T);
    printf("\n");
    postOrder(T);
    printf("\n");
    return 0;
}

层序遍历

``

/*************************************************************************
* File Name: treeLevelTraverse.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Thu 13 May 2021 07:03:14 PM CST
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
    char data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
}TreeNode;

typedef struct QueueNode {
    TreeNode* data;
    struct QueueNode* pre;
    struct QueueNode* next;
}QueueNode;

void createTree(TreeNode** T, char* data, int* index) {
    char ch;
    ch = data[*index];
    *index += 1;
    if (ch == '#') {
        *T = NULL;
    }
    else {
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = ch;
        createTree(&((*T)->lchild), data, index);
        createTree(&((*T)->rchild), data, index);
    }
}

void preOrder(TreeNode* T) {
    if (T == NULL) {
        return;
    }
    else {
        printf("%c ", T->data);
        preOrder(T->lchild);
        preOrder(T->rchild);
    }
}

QueueNode* initQueue() {
    QueueNode* Q = (QueueNode*)malloc(sizeof(QueueNode));
    Q->data = NULL;
    Q->next = Q;
    Q->pre = Q;
    return Q;
}

void enQueue(TreeNode* data, QueueNode* Q) {
    QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));
    node->data = data;
    node->pre = Q;
    node->next = Q;
    Q->pre->next = node;
    Q->pre = node;
}

int isEmpty(QueueNode* Q) {
    if (Q->next == Q) {
        return 1;
    }
    else {
        return 0;
    }
}

QueueNode* deQueue(QueueNode* Q) {
    if (isEmpty(Q)) {
        return NULL;
    }
    else {
        QueueNode* node = Q->next;
        Q->next->next->pre = Q;
        Q->next = Q->next->next;
        return node;
    }
}

void levelTraverse(QueueNode* Q, TreeNode* T) {
    enQueue(T, Q);//入队
    while (!isEmpty(Q)) {//队不为空
        QueueNode* node = deQueue(Q);//出队
        printf("%c ", node->data->data);
        if (node->data->lchild) {
            enQueue(node->data->lchild, Q);//入队
        }
        if (node->data->rchild) {
            enQueue(node->data->rchild, Q);//入队
        }
    }
}

int main (int argc, char* argv[]) {
    TreeNode* T;
    int index = 0;
    QueueNode* Q = initQueue();
    createTree(&T, argv[1], &index);
    preOrder(T);        
    printf("\n");
    levelTraverse(Q, T);
    printf("\n");
    return 0;
}

非递归遍历

先中序遍历

``

/*************************************************************************
* File Name: treeNonRecursive.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Sun 16 May 2021 05:51:25 PM CST
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
    char data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
}TreeNode;

typedef struct StackNode {
    TreeNode* data;
    struct StackNode* next;
}StackNode;

void createTree(TreeNode** T, char* data, int* index) {
    char ch;
    ch = data[*index];
    *index += 1;
    if (ch == '#') {
        // 此时为空节点
        *T = NULL;
    }
    else {
        // 此时不为空
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = ch;
        // 创建左子树,逻辑一致,进行递归
        createTree(&((*T)->lchild), data, index);
        // 创建右子树,逻辑一致,进行递归
        createTree(&((*T)->rchild), data, index);
    }
}

StackNode* initStack() {
    StackNode* S = (StackNode*)malloc(sizeof(StackNode));
    S->data = NULL;
    S->next = NULL;
    return S;
}

void push(TreeNode* data, StackNode* S) {
    StackNode* node = (StackNode*)malloc(sizeof(StackNode));
    node->data = data;
    node->next = S->next;
    S->next = node;
}

int isEmpty(StackNode* S) {
    if (S->next == NULL) {
        return 1;
    }
    else {
        return 0;
    }
}

StackNode* pop(StackNode* S) {
    if (isEmpty(S)) {
        return NULL;
    }
    else {
        StackNode* node = S->next;
        S->next = node->next;
        return node;
    }
}

void preOrder(TreeNode* T) {
    TreeNode* node = T;
    StackNode* S = initStack();//初始化栈
    while (node || !isEmpty(S)) {
        if (node) {
            printf("%c ", node->data);
            push(node, S);
            node = node->lchild;
        }
        else {
            node = pop(S) -> data;
            node = node->rchild;
        }
    }
}

void inOrder(TreeNode* T) {
    TreeNode* node = T;
    StackNode* S = initStack();
    while (node || !isEmpty(S)) {
        if (node) {
            push(node, S);
            node = node->lchild;
        }
        else {
            node = pop(S) -> data;
            printf("%c ", node->data);
            node = node->rchild;
        }
    }
}

int main(int argc, char* argv[]) {
    TreeNode* T;
    int index = 0;
    createTree(&T, argv[1], &index);
    preOrder(T);
    printf("\n");
    inOrder(T);
    printf("\n");
    return 0;
}
后序遍历

``

/*************************************************************************
* File Name: treeNonRecursivePost.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Sun 04 Jul 2021 02:24:42 PM CST
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
    char data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
    int flag;
}TreeNode;

typedef struct StackNode {
    TreeNode* data;
    struct StackNode* next;
}StackNode;

void createTree(TreeNode** T, char* data, int* index) {
    char ch;
    ch = data[*index];
    *index += 1;
    if (ch == '#') {
        // 此时为空节点
        *T = NULL;
    }
    else {
        // 此时不为空
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = ch;
        (*T) -> flag = 0;
        // 创建左子树,逻辑一致,进行递归
        createTree(&((*T)->lchild), data, index);
        // 创建右子树,逻辑一致,进行递归
        createTree(&((*T)->rchild), data, index);
    }
}

StackNode* initStack() {
    StackNode* S = (StackNode*)malloc(sizeof(StackNode));
    S->data = NULL;
    S->next = NULL;
    return S;
}

void push(TreeNode* data, StackNode* S) {
    StackNode* node = (StackNode*)malloc(sizeof(StackNode));
    node->data = data;
    node->next = S->next;
    S->next = node;
}

int isEmpty(StackNode* S) {
    if (S->next == NULL) {
        return 1;
    }
    else {
        return 0;
    }
}

StackNode* pop(StackNode* S) {
    if (isEmpty(S)) {
        return NULL;
    }
    else {
        StackNode* node = S->next;
        S->next = node->next;
        return node;
    }
}

StackNode* getTop(StackNode* S) {
    if (isEmpty(S)) {
        return NULL;
    }
    else {
        StackNode* node = S->next;
        return node;
    }
}

void postOrder(TreeNode* T) {
    TreeNode* node = T;
    StackNode* S = initStack();
    while (node || !isEmpty(S)) {
        if (node) {
            push(node, S);
            node = node -> lchild;
        }
        else {
            TreeNode* top = getTop(S) -> data;
            if (top -> rchild && top -> rchild -> flag == 0) {
                top = top -> rchild;
                push(top, S);
                node = top -> lchild;
            }
            else {
                top = pop(S) -> data;
                printf("%c ", top -> data);
                top -> flag = 1;
            }
        }
    }
}

int main(int argc, char* argv[]) {
    TreeNode* T;
    int index = 0;
    createTree(&T, argv[1], &index);
    postOrder(T);
    printf("\n");
    return 0;
}

线索二叉树

使用线索将二叉树转换为一个类似的线性结构

线索是将节点连在一起的指针

二叉树有2n个指针,n-1个指针指向节点,还剩n+1个指针用来指向二叉树遍历中时的前驱与后驱

中序线索二叉树
/*************************************************************************
* File Name: inThreadTree.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Wed 07 Jul 2021 09:14:08 PM CST
 ************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
    char data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
    int ltag;
    int rtag;
}TreeNode;

void createTree(TreeNode** T, char* data, int* index) {
    char ch;
    ch = data[*index];
    *index += 1;
    if (ch == '#') {
        // 此时为空节点
        *T = NULL;
    }
    else {
        // 此时不为空
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = ch;
        (*T) -> ltag = 0;
        (*T) -> rtag = 0;
        // 创建左子树,逻辑一致,进行递归
        createTree(&((*T)->lchild), data, index);
        // 创建右子树,逻辑一致,进行递归
        createTree(&((*T)->rchild), data, index);
    }
}

void inThreadTree(TreeNode* T, TreeNode** pre) {
    if (T) {
        inThreadTree(T -> lchild, pre);
        // do something
        if (T -> lchild == NULL) {
            T -> ltag = 1;
            T -> lchild = *pre;
        }
        if (*pre != NULL && (*pre) -> rchild == NULL) {
            (*pre) -> rtag = 1;
            (*pre) -> rchild = T;
        }
        *pre = T;
        //
        inThreadTree(T -> rchild, pre);
    }
}

TreeNode* getFirst(TreeNode* T) {
    while (T -> ltag == 0)
        T = T -> lchild;
    return T;
}

TreeNode* getNext(TreeNode* node) {
    if (node -> rtag == 1)
        return node -> rchild;
    else
        return getFirst(node -> rchild);
}

int main(int argc, char* argv[]) {
    TreeNode* T;
    TreeNode* pre = NULL;
    int index = 0;
    createTree(&T, argv[1], &index);
    inThreadTree(T, &pre);
    pre -> rtag = 1;
    pre -> rchild = NULL;
    for (TreeNode* node = getFirst(T); node != NULL; node = getNext(node)) {
        printf("%c ", node -> data);
    }
    printf("\n");
    return 0;
}
先序线索二叉树

不懂

/*************************************************************************
* File Name: preThreadTree.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Wed 07 Jul 2021 09:14:08 PM CST
 ************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
    char data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
    int ltag;
    int rtag;
}TreeNode;

void createTree(TreeNode** T, char* data, int* index) {
    char ch;
    ch = data[*index];
    *index += 1;
    if (ch == '#') {
        // 此时为空节点
        *T = NULL;
    }
    else {
        // 此时不为空
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = ch;
        (*T) -> ltag = 0;
        (*T) -> rtag = 0;
        // 创建左子树,逻辑一致,进行递归
        createTree(&((*T)->lchild), data, index);
        // 创建右子树,逻辑一致,进行递归
        createTree(&((*T)->rchild), data, index);
    }
}

void preThreadTree(TreeNode* T, TreeNode** pre) {
    if (T) {
        if (T -> lchild == NULL) {
            T -> ltag = 1;
            T -> lchild = *pre;
        }
        if (*pre != NULL && (*pre) -> rchild == NULL) {
            (*pre) -> rtag = 1;
            (*pre) -> rchild = T;
        }
        *pre = T;
        if (T -> ltag == 0) 
            preThreadTree(T -> lchild, pre);
        preThreadTree(T -> rchild, pre);
    }
}

TreeNode* getNext(TreeNode* node) {
    if (node -> rtag == 1 || node -> ltag == 1)
        return node -> rchild;
    else
        return node -> lchild;
}

int main(int argc, char* argv[]) {
    TreeNode* T;
    TreeNode* pre = NULL;
    int index = 0;
    createTree(&T, argv[1], &index);
    preThreadTree(T, &pre);
    pre -> rtag = 1;
    pre -> rchild = NULL;
    for (TreeNode* node = T; node != NULL; node = getNext(node)) {
        printf("%c ", node -> data);
    }
    printf("\n");
    return 0;
}
后序线索二叉树

不懂

/*************************************************************************
* File Name: postThreadTree.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Wed 07 Jul 2021 09:14:08 PM CST
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

typedef struct TreeNode {
    char data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
    struct TreeNode* parent;
    int ltag;
    int rtag;
}TreeNode;

void createTree(TreeNode** T, char* data, int* index, TreeNode* parent) {
    char ch;
    ch = data[*index];
    *index += 1;
    if (ch == '#') {
        // 此时为空节点
        *T = NULL;
    }
    else {
        // 此时不为空
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = ch;
        (*T) -> ltag = 0;
        (*T) -> rtag = 0;
        (*T) -> parent = parent;
        // 创建左子树,逻辑一致,进行递归
        createTree(&((*T)->lchild), data, index, *T);
        // 创建右子树,逻辑一致,进行递归
        createTree(&((*T)->rchild), data, index, *T);
    }
}

void postThreadTree(TreeNode* T, TreeNode** pre) {
    if (T) {
        postThreadTree(T -> lchild, pre);
        postThreadTree(T -> rchild, pre);
        // do something
        if (T -> lchild == NULL) {
            T -> ltag = 1;
            T -> lchild = *pre;
        }
        if (*pre != NULL && (*pre) -> rchild == NULL) {
            (*pre) -> rtag = 1;
            (*pre) -> rchild = T;
        }
        *pre = T;
    }
}

TreeNode* getFirst(TreeNode* T) {
    while (T -> ltag == 0)
        T = T -> lchild;
    if (T -> rtag == 0) {
        return getFirst(T -> rchild);
    }
    return T;
}

TreeNode* getNext(TreeNode* node) {
    if (node -> rtag == 1)
        return node -> rchild;
    else {
        // 如果是根节点
        if (node -> parent == NULL) {
            return NULL;
        }
        // 如果是右孩子
        else if (node -> parent -> rchild == node) {
            return node -> parent;
        }
        // 如果是左孩子
        else {
            if (node -> parent -> ltag == 0) {
                return getFirst(node -> parent -> rchild);
            }
            else {
                return node -> parent;
            }
        }
    }
}

int main(int argc, char* argv[]) {
    TreeNode* T;
    TreeNode* pre = NULL;
    int index = 0;
    createTree(&T, argv[1], &index, NULL);
    postThreadTree(T, &pre);
    for (TreeNode* node = getFirst(T); node != NULL; node = getNext(node)) {
        printf("%c ", node -> data);
    }
    printf("\n");
    return 0;
}

二叉排序树

/*************************************************************************
* File Name: binarySearchTree.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Wed 14 Jul 2021 11:11:49 PM CST
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
    int data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
}TreeNode;

TreeNode* bstSearch(TreeNode* T,  int data) {
    if (T) {
        if (T -> data == data) {
            return T;
        }
        else if (data < T -> data) {
            return bstSearch(T -> lchild, data);
        }
        else {
            return bstSearch(T -> rchild, data);
        }
    }
    else {
        return NULL;
    }
}

void bstInsert(TreeNode** T, int data) {
    if (*T == NULL) {
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = data;
        (*T) -> lchild = NULL;
        (*T) -> rchild = NULL;
    } 
    else if (data == (*T) -> data) {
        return;
    }
    else if (data < (*T) -> data) {
        bstInsert(&((*T) -> lchild), data);
    }
    else {
        bstInsert(&((*T) -> rchild), data);
    }
}

void preOrder(TreeNode* T) {
    if (T) {
        printf("%d ", T -> data);
        preOrder(T -> lchild);
        preOrder(T -> rchild);
    }
}

int main() {
    TreeNode* T = NULL;
    int nums[6] = {8, 6, 10, 9, 11, 23};
    for (int i = 0; i < 6; i++) {
        bstInsert(&T, nums[i]);
    }
    preOrder(T);
    printf("\n");
}

平衡二叉树

什么是平衡二叉树

是一个合理的二叉树

如何保证合理

平衡二叉树左右子树高度茶不超过1

如何构建平衡二叉树

1.本质与构建二叉排序树一样

2.在构建二叉排序树时,发现树不合理,进行调整

如何判断调整类型
类型:

LL,RR,RL,LR

如何判断

1.找到失衡树的根节点–root

2.找到导致树失衡的结点–node,判断node在root的那一侧

3.判断node在root孩子的哪一侧

4.如果有多个树不平衡,选择最小树,开始

原理实现过程
1.RR型

取中间结点,作为父节点,让其父亲成为它的左孩子,若它本身有左孩子,则接到父亲的右孩子处

2.LL型

取中间结点,作为父节点,让其父亲成为它的右孩子,若他有右孩子,则接到父亲的左孩子处

3.LR型

取最后结点,作为父节点,让其父节点成为他的左孩子,让其父节点的父节点成为他的右孩子。

如果他有左孩子,则左孩子接到父节点的右孩子处,

如果他有右孩子,则右孩子接到父节点的父节点的左孩子处

4.RL型

取最后结点,作为父节点,让其父节点成为他的右孩子,让其父节点的父节点成为他的左孩子。

如果他有左孩子,则左孩子接到父节点的父节点的右孩子处,

如果他有右孩子,则右孩子接到父节点的左孩子处

代码实现过程
/*************************************************************************
* File Name: avlTree.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Sat 17 Jul 2021 06:24:32 PM CST
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode {
    int data;
    int height;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
}TreeNode;

int getHeight(TreeNode* node) {
    return node ? node -> height : 0;
}

int max(int a, int b) {
    return a > b ? a : b;
}

void rrRotation(TreeNode* node, TreeNode** root) {
    TreeNode* temp = node -> rchild;
    node -> rchild = temp -> lchild;
    temp -> lchild = node;
    node -> height = max(getHeight(node -> lchild), getHeight(node -> rchild)) + 1;
    temp -> height = max(getHeight(temp -> lchild), getHeight(temp -> rchild)) + 1;
    *root = temp;
}

void llRotation(TreeNode* node, TreeNode** root) {
    TreeNode* temp = node -> lchild;
    node -> lchild = temp -> rchild; 
    temp -> rchild = node;
    node -> height = max(getHeight(node -> lchild), getHeight(node -> rchild)) + 1;
    temp -> height = max(getHeight(temp -> lchild), getHeight(temp -> rchild)) + 1;
    *root = temp;
}

void avlInsert(TreeNode** T, int data) {
    if (*T == NULL) {
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = data;
        (*T) -> height = 0;
        (*T) -> lchild = NULL;
        (*T) -> rchild = NULL;
    }
    else if (data < (*T) -> data) {
        avlInsert(&(*T) -> lchild, data);
        // 拿到当前节点左右子树的高度
        int lHeight = getHeight((*T) -> lchild);
        int rHeight = getHeight((*T) -> rchild);
        // 判断高度差
        if (lHeight - rHeight == 2) {
            if (data < (*T) -> lchild -> data) {
                // LL 调整
                llRotation(*T, T);
            }
            else {
                // LR 调整
                rrRotation((*T) -> lchild, &(*T) -> lchild);
                llRotation(*T, T);
            }
        }
    }
    else if (data > (*T) -> data) {
        avlInsert(&(*T) -> rchild, data);
        // 拿到当前节点左右子树的高度
        int lHeight = getHeight((*T) -> lchild);
        int rHeight = getHeight((*T) -> rchild);
        // 判断高度差
        if (rHeight - lHeight == 2) {
            if (data > (*T) -> rchild -> data) {
                // RR 调整
                rrRotation(*T, T);
            }
            else {
                // RL 调整
                llRotation((*T) -> rchild, &(*T) -> rchild);
                rrRotation(*T, T);
            }
        }
    }
    (*T) -> height = max(getHeight((*T) -> lchild), getHeight((*T) -> rchild)) + 1;
}

void preOrder(TreeNode* T) {
    if (T) {
        printf("%d ", T -> data);
        preOrder(T -> lchild);
        preOrder(T -> rchild);
    }
}

int main() {
    TreeNode* T = NULL;
    int nums[5] = {1,8,6,7,10};
    for (int i = 0; i < 5; i++) {
        avlInsert(&T, nums[i]);
    }
    preOrder(T);
    printf("\n");
}

哈夫曼树

什么是哈夫曼树

使所有叶子结点的带权路径长度最小

代码实现
/*************************************************************************
* File Name: huffmanTree.c
* Author: TyrantLucifer
* E-mail: TyrantLucifer@gmail.com
* Blog: https://tyrantlucifer.com
* Created Time: Wed 21 Jul 2021 08:57:59 PM CST
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
    
typedef struct TreeNode {
    int parent;
    int lchild;
    int rchild;
}TreeNode;

typedef struct HFTree {
    TreeNode* data;
    int length;
}HFTree;

HFTree* initTree(int* weight,  in
    int weight;t length) {
    HFTree* T = (HFTree*)malloc(sizeof(HFTree));
    T -> data = (TreeNode*)malloc(sizeof(TreeNode) * (2 * length - 1));
    T -> length = length;
    for (int i = 0; i < length; i++) {
        T -> data[i].weight = weight[i];
        T -> data[i].parent = 0;
        T -> data[i].lchild = -1;
        T -> data[i].rchild = -1;
    } 
    return T;
}

int* selectMin(HFTree* T) {
    int min = 10000;
    int secondMin = 10000;
    int minIndex;
    int secondIndex;
    for (int i = 0; i < T -> length; i++) {
        if (T -> data[i].parent == 0) {
            if (T -> data[i].weight < min) {
                min = T -> data[i].weight;
                minIndex = i;
            } 
        }
    }
    for (int i = 0; i < T -> length; i++) {
        if (T -> data[i].parent == 0 && i != minIndex) {
            if (T -> data[i].weight < secondMin) {
                secondMin = T -> data[i].weight;
                secondIndex = i;
            } 
        }
    }
    int* res = (int*)malloc(sizeof(int)* 2);
    res[0] = minIndex;
    res[1] = secondIndex;
    return res;
}

void createHFTree(HFTree* T) {
    int* res;
    int min;
    int secondMin;
    int length = T -> length * 2 - 1;
    for (int i = T -> length; i < length; i++) {
        res = selectMin(T);
        min = res[0];
        secondMin = res[1];
        T -> data[i].weight = T -> data[min].weight + T -> data[secondMin].weight;
        T -> data[i].lchild = min;
        T -> data[i].rchild = secondMin;
        T -> data[i].parent = 0;
        T -> data[min].parent = i;
        T -> data[secondMin].parent = i;
        T -> length ++;
    }
}

void preOrder(HFTree* T, int index) {
    if (index != -1) {
        printf("%d ", T -> data[index].weight);
        preOrder(T, T -> data[index].lchild);
        preOrder(T, T -> data[index].rchild);
    }
}

int main() {
    int weight[7] = {5,1,3,6,11,2,4};
    HFTree* T = initTree(weight, 7);
    createHFTree(T);
    preOrder(T, T -> length - 1);
    printf("\n");
    return 0;
}
哈夫曼编码

一般左子树为0,右子树为1


# 代码

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define Max 32667

typedef struct hnode{

       int l;

       int r;

       int parent;

       int weight;

}Hnode;

 typedef struct htree{

      Hnode *data;//存放整棵树

      int length;

 }Hftree;

//初始化哈希树

 Hftree * initTree(int weight[],int n)

 {

      Hftree *T=(Hftree*)malloc(sizeof(Hftree));

      T->length=n;//当前结点数量

      T->data=(Hnode*)malloc(sizeof(Hnode)*(2*n));//存放二叉树结点数量 2*n

      //初始化叶子节点

      for(int i=0;i<n;i++)

      {

             T->data[i].weight=weight[i];

             T->data[i].parent=0;//表示父节点不存在

             T->data[i].l=-1;

             T->data[i].r=-1;

        }

      return T;

 }

 //在已经存在的节点中寻找最小权值的两个节点,为他们生成父亲节点

 int* Selectmin(Hftree *T)

 {

      int *res=(int*)malloc(sizeof(int)*2);

      int min1=Max,min2=Max;

      int m1,m2;

      //寻找第一小的节点

      for(int i=0;i<T->length;i++)

      {

             if(T->data[i].parent==0 && T->data[i].weight<min1 )

             {

                    min1=T->data[i].weight;

                    m1=i;

               }

        }

        //寻找第二小的节点

             for(int i=0;i<T->length;i++)

            {

                   if(T->data[i].parent==0 && T->data[i].weight<min2  )

                   {

                          if(i!=m1)

                          {

                                 min2=T->data[i].weight;

                                   m2=i;

                            }

                     }

              }

      //数组存放的是第一小与第二小的权值的下标

      res[0]=m1;

      res[1]=m2;

    return res;

 }

void creatTree(Hftree * T)

{

       int *res;

       int l=T->length *2-1;//二叉树应该有的结点数量 2*n-1(n表示叶子节点的数量)

       for(int i=T->length;i<l;i++)//注意i 从T->length开始,前面都是叶子结点

       {

              res=Selectmin(T);

              int m1=res[0];//第一小下标

              int m2=res[1];//第二小下标

              T->data[m1].parent=i;

              T->data[i].l=m1;

              T->data[m2].parent=i;

              T->data[i].r=m1;

              T->data[i].weight=T->data[m1].weight+T->data[m2].weight;

              T->data[i].parent=0;

              T->length++;//注意现在实际结点长度++

       }

}

void Hfcode(Hftree *T,int l)

{

              //二维数组,储存哈夫曼编码

              char hfcode[6][6];

              char s[6]={'A','B','C','D','E','F'};

              //实现编码过程

              //注意每个叶子结点的编码是由下往上的,所以要倒着存储

              //储存单个字母的哈夫曼编码

              char code[l];

              code[l-1]='\0';

              for(int i=0;i<l;i++)

              {

                     int curent=i;

                     int start=l-1;

                     int f=T->data[curent].parent;

                     while(f!=0)

                     {

                                   --start;

                                   if(T->data[f].l==curent)

                                   {

                                          code[start]='0';

                                   }else{

                                          code[start]='1';

                                   }

                                   //向上遍历

                                   curent=f;

                                   f=T->data[f].parent;   

                     }

                     //完成一个节点的编码

                     strcpy(hfcode[i],&code[start]);

              }

              //输出编码

              for(int i=0;i<6;i++)

              {

                     printf("%c:%s\n",s[i],hfcode[i]);

              }            

}

int main()

{

       int weight[6]={15,9,8,12,10,5};

       //初始化哈希树

       Hftree*T=initTree(weight,6);

       //创建哈希树

       creatTree(T);

       //输出哈希码

       Hfcode(T,6);

       return 0;

}

图的创建与遍历

遍历方法
深度优先搜索----二叉树的前序遍历

1.找一个结点访问

2.找这个结点可以访问的下一个结点继续访问

3.重复以上,直到访问完毕

一条路走到黑,撞南墙才回头,回头后继续走然后撞南墙

广度优先搜索—二叉树的层次遍历
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 5

typedef struct Graph {
    char* vexs;
    int** arcs;
    int vexNum;
    int arcNum;
}Graph;

typedef struct Queue {
    int front;
    int rear;
    int data[MAXSIZE];
}Queue;

Queue* initQueue() {
    Queue* Q = (Queue*)malloc(sizeof(Queue));
    Q->front = Q->rear = 0;
    return Q;
}

int isFull(Queue* Q) {
    if ((Q->rear + 1) % MAXSIZE == Q->front) {
        return 1;
    }
    else {
        return 0;
    }
}

int isEmpty(Queue* Q) {
    if (Q->front == Q->rear) {
        return 1;
    }
    else {
        return 0;
    }
}

int enQueue(Queue* Q, int data) {
    if (isFull(Q)) {
        return 0;
    }
    else {
        Q->data[Q->rear] = data;
        Q->rear = (Q->rear + 1) % MAXSIZE;
        return 1;
    }
}

int deQueue(Queue* Q) {
    if(isEmpty(Q)) {
        return -1;
    }
    else {
        int data = Q->data[Q->front];
        Q->front = (Q->front + 1) % MAXSIZE;
        return data;
    }
}
Graph* initGraph(int vexNum) {
    Graph* G = (Graph*)malloc(sizeof(Graph));
    G -> vexs = (char*)malloc(sizeof(char) * vexNum);
    G -> arcs = (int**)malloc(sizeof(int*) * vexNum);
    for (int i = 0 ; i < vexNum; i++) {
        G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);
    }
    G -> vexNum = vexNum;
    G -> arcNum = 0;
    return G;
}

void createGraph(Graph* G, char* vexs, int* arcs) {
    for (int i = 0 ; i < G -> vexNum; i++) {
        G -> vexs[i] = vexs[i];
        for (int j = 0; j < G -> vexNum; j++) {
            G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);
            if (G -> arcs[i][j] != 0)
                G -> arcNum ++;
        }
    }
    G -> arcNum /= 2;
}

void DFS(Graph* G, int* visited, int index) {
    printf("%c\t", G -> vexs[index]);
    visited[index] = 1;
    for (int i = 0; i < G ->vexNum; i++) {
        if (G -> arcs[index][i] == 1 && !visited[i]) {
            DFS(G, visited, i);
        }
    }
}

void BFS(Graph* G, int* visited, int index) {
    Queue* Q = initQueue();
    printf("%c\t", G -> vexs[index]);
    visited[index] = 1;
    enQueue(Q, index);
    while (!isEmpty(Q)) {
        int i = deQueue(Q);
        for (int j = 0; j < G -> vexNum; j++) {
            if (G -> arcs[i][j] == 1 && !visited[j]) {
                printf("%c\t", G -> vexs[j]);
                visited[j] = 1;
                enQueue(Q, j);
            }
        }
    }
}

int main() {
    Graph* G = initGraph(5);
    int* visited = (int*)malloc(sizeof(int) * G -> vexNum);
    for (int i = 0; i < G -> vexNum; i++)
        visited[i] = 0;
    int arcs[5][5] = {
        0,1,1,1,0,
        1,0,1,1,1,
        1,1,0,0,0,
        1,1,0,0,1,
        0,1,0,1,0
    };
    createGraph(G, "ABCDE", (int*)arcs);
    DFS(G, visited, 0);
    printf("\n");
    for (int i = 0; i < G -> vexNum; i++)
        visited[i] = 0;
    BFS(G, visited, 0);
    printf("\n");
    return 0;
}

最小生成树

primer算法

定下顶点,在顶点的边中选取一个最小的边
邻接矩阵的值 —权值

  • 图顶点之前不通,那么邻接矩阵的值为MAX
  • 如果顶点是自己本身,那么值为0
#include <stdio.h>
#include <stdlib.h>


#define MAX 32767

typedef struct Graph {
    char* vexs;
    int** arcs;
    int vexNum;
    int arcNum;
}Graph;
//矩阵中记录每一行的值,且记录起始结点
typedef struct Edge {
    char vex;//记录最小边的起始结点
    int weight;//记录权值
}Edge;

/**
 * 当edge.weight = 0时,代表顶点加入到U集合中
 */ 
Edge* initEdeg(Graph* G, int index) {
    Edge* edge = (Edge*)malloc(sizeof(Edge) * G -> vexNum);
    for (int i = 0; i < G ->vexNum; i++) {
        edge[i].vex = G -> vexs[index]; 
        edge[i].weight = G -> arcs[index][i];
    }
    return edge;
}

int getMinEdge(Edge* edge, Graph* G) {
    int index;
    int min = MAX;
    for (int i = 0; i < G -> vexNum; i++) {
        if (edge[i].weight != 0 && min > edge[i].weight) {
            min = edge[i].weight;
            index = i;
        }
    }
    return index;
}

void prim(Graph* G, int index) {
    int min;
    Edge* edge = initEdeg(G, index);
    for (int i = 0; i < G -> vexNum - 1; i++) {
        min = getMinEdge(edge, G);
        printf("v%c --> v%c, weight = %d\n", edge[min].vex, G -> vexs[min], edge[min].weight);
        edge[min].weight = 0;
        for (int j = 0; j < G -> vexNum; j++) {
            if (G -> arcs[min][j] < edge[j].weight) {
                edge[j].weight = G -> arcs[min][j];
                edge[j].vex = G -> vexs[min];
            }
        }
    }
} 

Graph* initGraph(int vexNum) {
    Graph* G = (Graph*)malloc(sizeof(Graph));
    G -> vexs = (char*)malloc(sizeof(char) * vexNum);
    G -> arcs = (int**)malloc(sizeof(int*) * vexNum);
    for (int i = 0 ; i < vexNum; i++) {
        G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);
    }
    G -> vexNum = vexNum;
    G -> arcNum = 0;
    return G;
}

void createGraph(Graph* G, char* vexs, int* arcs) {
    for (int i = 0 ; i < G -> vexNum; i++) {
        G -> vexs[i] = vexs[i];
        for (int j = 0; j < G -> vexNum; j++) {
            G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);
            if (G -> arcs[i][j] != 0 && G -> arcs[i][j] != MAX)  
                G -> arcNum ++;
        }
    }
    G -> arcNum /= 2;
}

void DFS(Graph* G, int* visited, int index) {
    printf("%c\t", G -> vexs[index]);
    visited[index] = 1;
    for (int i = 0; i < G ->vexNum; i++) {
        if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX && !visited[i]) {
            DFS(G, visited, i);
        }
    }
}

int main() {
    Graph* G = initGraph(6);
    int* visited = (int*)malloc(sizeof(int) * G -> vexNum);
    for (int i = 0; i < G -> vexNum; i++)
        visited[i] = 0;
    int arcs[6][6] = {
        0, 6, 1, 5, MAX, MAX,
        6, 0, 5, MAX, 3, MAX,
        1, 5, 0, 5, 6, 4,
        5, MAX, 5, 0, MAX, 2,
        MAX, 3, 6, MAX, 0, 6,
        MAX, MAX, 4, 2, 6, 0
    };
    createGraph(G, "123456", (int*)arcs);
    DFS(G, visited, 0);
    printf("\n");
    prim(G, 0);
    return 0;
}
Kruskal算法

首先找到最小的边

#include <stdio.h>
#include <stdlib.h>
#define MAX 32767
//图结构定义
typedef struct Graph {
    char* vexs;
    int** arcs;
    int vexNum;
    int arcNum;
}Graph;

typedef struct Edge {
    int start;
    int end;
    int weight;
}Edge;

Edge* initEdge(Graph* G) {
    int index = 0;
    Edge* edge = (Edge*)malloc(sizeof(Edge) * G -> arcNum);
    for (int i = 0; i < G -> vexNum; i++) {
        for (int j = i + 1; j < G -> vexNum; j++) {
            if (G -> arcs[i][j] != MAX) {
                edge[index].start = i;
                edge[index].end = j;
                edge[index].weight = G -> arcs[i][j];
                index++;
            }
        }
    }
    return edge;
}

void sortEdge(Edge* edge, Graph* G) {
    Edge temp;
    for (int i = 0; i < G -> arcNum - 1; i++) {
        for (int j = 0; j < G -> arcNum - i - 1; j++) {
            if (edge[j].weight > edge[j + 1].weight) {
                temp = edge[j];
                edge[j] = edge[j + 1];
                edge[j + 1] = temp;
            }
        }
    }
}

void kruskal(Graph* G) {
    int* connected = (int*)malloc(sizeof(int) * G -> vexNum);
    
    for (int i = 0 ; i < G -> vexNum; i++) {
        connected[i] = i;
    }
    
    Edge* edge = initEdge(G);
    //由小到大排列
    sortEdge(edge, G);
    
    for (int i = 0; i < G -> arcNum; i++) {
        int start = connected[edge[i].start];
        int end = connected[edge[i].end];
        if (start != end) {
            printf("v%c --> v%c weight = %d\n", G -> vexs[edge[i].start], G -> vexs[edge[i].end], edge[i].weight);
            for (int j = 0; j < G -> vexNum; j++) {
                if (connected[j] == end) {
                    connected[j] = start;
                }
            }
        }
    }
}

//初始化图
Graph* initGraph(int vexNum) {
    Graph* G = (Graph*)malloc(sizeof(Graph));
    G -> vexs = (char*)malloc(sizeof(char) * vexNum);
    G -> arcs = (int**)malloc(sizeof(int*) * vexNum);
    for (int i = 0 ; i < vexNum; i++) {
        G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);
    }
    G -> vexNum = vexNum;
    G -> arcNum = 0;
    return G;
}

void createGraph(Graph* G, char* vexs, int* arcs) {
    for (int i = 0 ; i < G -> vexNum; i++) {
        G -> vexs[i] = vexs[i];
        for (int j = 0; j < G -> vexNum; j++) {
            G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);
            if (G -> arcs[i][j] != 0 && G -> arcs[i][j] != MAX)
                G -> arcNum ++;
        }
    }
    G -> arcNum /= 2;
}

void DFS(Graph* G, int* visited, int index) {
    printf("%c\t", G -> vexs[index]);
    visited[index] = 1;
    for (int i = 0; i < G ->vexNum; i++) {
        if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX && !visited[i]) {
            DFS(G, visited, i);
        }
    }
}

int main() {
    Graph* G = initGraph(6);
    int* visited = (int*)malloc(sizeof(int) * G -> vexNum);
    for (int i = 0; i < G -> vexNum; i++)
        visited[i] = 0;
    
    int arcs[6][6] = {
        0, 6, 1, 5, MAX, MAX,
        6, 0, 5, MAX, 3, MAX,
        1, 5, 0, 5, 6, 4,
        5, MAX, 5, 0, MAX, 2,
        MAX, 3, 6, MAX, 0, 6,
        MAX, MAX, 4, 2, 6, 0
    };
    
    createGraph(G, "123456", (int*)arcs);
    DFS(G, visited, 0);
    printf("\n");
    kruskal(G);
    return 0;
}

最短路径

floyd算法

#include <stdio.h>  
#include <stdlib.h>  
  
#define MAX 32767  
  
typedef struct Graph {  
    char* vexs;  
    int** arcs;  
    int vexNum;  
    int arcNum;  
}Graph;  
  
Graph* initGraph(int vexNum) {  
    Graph* G = (Graph*)malloc(sizeof(Graph));  
    G -> vexs = (char*)malloc(sizeof(char) * vexNum);  
    G -> arcs = (int**)malloc(sizeof(int*) * vexNum);  
    for (int i = 0 ; i < vexNum; i++) {  
        G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);  
    }  
    G -> vexNum = vexNum;  
    G -> arcNum = 0;  
    return G;  
}  
  
void createGraph(Graph* G, char* vexs, int* arcs) {  
    for (int i = 0 ; i < G -> vexNum; i++) {  
        G -> vexs[i] = vexs[i];  
        for (int j = 0; j < G -> vexNum; j++) {  
            G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);  
            if (G -> arcs[i][j] != 0 && G -> arcs[i][j] != MAX)   
                G -> arcNum ++;  
        }  
    }  
    G -> arcNum /= 2;  
}  
  
void DFS(Graph* G, int* visited, int index) {  
    printf("%c\t", G -> vexs[index]);  
    visited[index] = 1;  
    for (int i = 0; i < G ->vexNum; i++) {  
        if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX && !visited[i]) {  
            DFS(G, visited, i);  
        }  
    }  
}  
  
void floyd(Graph* G) {  
    int d[G -> vexNum][G -> vexNum];  
    int p[G -> vexNum][G -> vexNum];  
    for (int i = 0; i < G -> vexNum; i++) {  
        for (int j = 0; j < G -> vexNum; j++) {  
            d[i][j] = G -> arcs[i][j];  
            if (G -> arcs[i][j] > 0 && G -> arcs[i][j] != MAX) {  
                p[i][j] = i;  
            }  
            else  
                p[i][j] = -1;  
        }  
    }  
  
    for (int i = 0; i < G -> vexNum; i++) {  
        for (int j = 0; j < G -> vexNum; j++) {  
            for (int k = 0; k < G -> vexNum; k++) {  
                if (d[j][i] + d[i][k] < d[j][k]) {  
                    d[j][k] = d[j][i] + d[i][k];  
                    p[j][k] = p[i][k];  
                }  
            }  
        }  
    }  
  
    for (int i = 0; i < G -> vexNum; i++) {  
        for (int j = 0; j < G -> vexNum; j++) {  
            printf("%d ", d[i][j]);  
        }  
        printf("\n");  
    }  
    printf("\n");  
    for (int i = 0; i < G -> vexNum; i++) {  
        for (int j = 0; j < G -> vexNum; j++) {  
            printf("%d ", p[i][j]);  
        }  
        printf("\n");  
    }  
}  
  
int main() {  
    Graph* G = initGraph(4);  
    int* visited = (int*)malloc(sizeof(int) * G -> vexNum);  
    for (int i = 0; i < G -> vexNum; i++)  
        visited[i] = 0;  
    int arcs[4][4] = {  
        0, 1, MAX, 3,  
        1, 0, 2, 2,  
        MAX, 2, 0, 8,  
        3, 2, 8, 0  
    };  
    createGraph(G, "1234", (int*)arcs);  
    DFS(G, visited, 0);  
    printf("\n");  
    floyd(G);  
    return 0;  
}
dijiaskra算法

三个数组
S数组:记录目标顶点到其他顶点的最短距离是否求得
p数组:记录目标顶点到其他顶点最短路径的前驱结点
D数组:记录目标顶点到其他顶点的最短路径长度

			#include <stdio.h>  
			#include <stdlib.h>  
			  
			#define MAX 32767  
			  
			typedef struct Graph {  
			    char* vexs;  
			    int** arcs;  
			    int vexNum;  
			    int arcNum;  
			}Graph;  
			  
			Graph* initGraph(int vexNum) {  
			    Graph* G = (Graph*)malloc(sizeof(Graph));  
			    G -> vexs = (char*)malloc(sizeof(char) * vexNum);  
			    G -> arcs = (int**)malloc(sizeof(int*) * vexNum);  
			    for (int i = 0 ; i < vexNum; i++) {  
			        G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);  
			    }  
			    G -> vexNum = vexNum;  
			    G -> arcNum = 0;  
			    return G;  
			}  
			  
			void createGraph(Graph* G, char* vexs, int* arcs) {  
			    for (int i = 0 ; i < G -> vexNum; i++) {  
			        G -> vexs[i] = vexs[i];  
			        for (int j = 0; j < G -> vexNum; j++) {  
			            G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);  
			            if (G -> arcs[i][j] != 0 && G -> arcs[i][j] != MAX)  
			                G -> arcNum ++;  
			        }  
			    }  
			    G -> arcNum /= 2;  
			}  
			  
			void DFS(Graph* G, int* visited, int index) {  
			    printf("%c\t", G -> vexs[index]);  
			    visited[index] = 1;  
			    for (int i = 0; i < G ->vexNum; i++) {  
			        if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX && !visited[i]) {  
			            DFS(G, visited, i);  
			        }  
			    }  
			}  
			  
			int getMin(int* d, int* s, Graph* G) {  
			    int min = MAX;  
			    int index;  
			    for (int i = 0; i < G -> vexNum; i++) {  
			        if (!s[i] && d[i] < min) {  
			            min = d[i];  
			            index = i;  
			        }  
			    }  
			    return index;  
			}  
			  
			void dijkstra(Graph* G, int index) {  
			    // 准备辅助数组  
			    int* s = (int*)malloc(sizeof(int) * G -> vexNum);  
			    int* p = (int*)malloc(sizeof(int) * G -> vexNum);  
			    int* d = (int*)malloc(sizeof(int) * G -> vexNum);  
			    // 初始化辅助数组  
			    for (int i = 0; i < G -> vexNum; i++) {  
			        if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX) {  
			            d[i] = G -> arcs[index][i];  
			            p[i] = index;  
			        }  
			        else {  
			            d[i] = MAX;  
			            p[i] = -1;  
			        }  
			        if (i == index) {  
			            s[i] = 1;  
			            d[i] = 0;  
			        }  
			        else  
			            s[i] = 0;  
			    }  
			    for (int i = 0; i < G -> vexNum - 1; i++) {  
			        int index = getMin(d, s, G);  
			        s[index] = 1;  
			        for (int j = 0; j < G -> vexNum; j++) {  
			            if (!s[j] && d[index] + G -> arcs[index][j] < d[j]) {  
			                d[j] = d[index] + G -> arcs[index][j];  
			                p[j] = index;  
			            }  
			        }  
			    }  
			    for (int i = 0; i < G ->vexNum; i++) {  
			        printf("%d %d %d\n", s[i], p[i], d[i]);  
			    }  
			}  
			  
			int main() {  
			    Graph* G = initGraph(7);  
			    int* visited = (int*)malloc(sizeof(int) * G -> vexNum);  
			    for (int i = 0; i < G -> vexNum; i++)  
			        visited[i] = 0;  
			    int arcs[7][7] = {  
			        0, 12, MAX, MAX, MAX, 16, 14,  
			        12, 0, 10, MAX, MAX, 7, MAX,  
			        MAX, 10, 0, 3, 5, 6, MAX,  
			        MAX, MAX, 3, 0, 4, MAX, MAX,  
			        MAX, MAX, 5, 4, 0, 2, 8,  
			        16, 7, 6, MAX, 2, 0, 9,  
			        14, MAX, MAX, MAX, 8, 9, 0  
			    };  
			    createGraph(G, "1234567", (int*)arcs);  
			    DFS(G, visited, 0);  
			    printf("\n");  
			    dijkstra(G, 0);  
			    return 0;  
		}
		
	

拓扑排序

#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct Graph {  
    char* vexs;  
    int** arcs;  
    int vexNum;  
    int arcNum;  
}Graph;  
  
typedef struct Node {  
    int data;  
    struct Node* next;  
}Node;  
  
Node* initStack() {  
    Node* stack = (Node*)malloc(sizeof(Node));  
    stack -> data = 0;  
    stack -> next = NULL;  
    return stack;  
}  
  
int isEmpty(Node* stack) {  
    if (stack -> next == NULL) {  
        return 1;  
    }  
    else {  
        return 0;  
    }  
}  
  
void push(Node* stack, int data) {  
    Node* node = (Node*)malloc(sizeof(Node));  
    node -> data = data;  
    node -> next = stack -> next;  
    stack -> next = node;  
    stack -> data ++;  
}  
  
int pop(Node* stack) {  
    if (!isEmpty(stack)) {  
        Node* node = stack -> next;  
        stack -> next = node -> next;  
        return node -> data;  
    }  
    else {  
        return -1;  
    }  
}  
  
int* findInDegrees(Graph* G) {  
    int* inDegrees = (int*)malloc(sizeof(int) * G -> vexNum);  
    for (int i = 0; i < G -> vexNum; i++) {  
        inDegrees[i] = 0;  
    }  
    for (int i = 0 ; i < G -> vexNum; i++) {  
        for (int j = 0; j < G -> vexNum; j++) {  
            if (G -> arcs[i][j])  
                inDegrees[j] = inDegrees[j] + 1;  
        }  
    }  
    return inDegrees;  
}  
  
void topologicalSort(Graph* G) {  
    int index = 0;  
    int* top = (int*)malloc(sizeof(int) * G -> vexNum);  
    int* inDegrees = findInDegrees(G);  
    Node* stack = initStack();  
    for (int i = 0 ; i < G -> vexNum; i++) {  
        if (inDegrees[i] == 0) {  
            push(stack, i);  
        }  
    }  
    while (!isEmpty(stack)) {  
        int vex = pop(stack);  
        top[index++] = vex;  
        for (int i = 0 ; i < G -> vexNum; i++) {  
            if (G -> arcs[vex][i]) {  
                inDegrees[i] = inDegrees[i] - 1;  
                if (inDegrees[i] == 0)   
                    push(stack, i);  
            }  
        }  
    }  
    for (int i = 0; i < index; i++) {  
        printf("%c ", G -> vexs[top[i]]);  
    }  
    printf("\n");  
}  
  
Graph* initGraph(int vexNum) {  
    Graph* G = (Graph*)malloc(sizeof(Graph));  
    G -> vexs = (char*)malloc(sizeof(char) * vexNum);  
    G -> arcs = (int**)malloc(sizeof(int*) * vexNum);  
    for (int i = 0 ; i < vexNum; i++) {  
        G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);  
    }  
    G -> vexNum = vexNum;  
    G -> arcNum = 0;  
    return G;  
}  
  
void createGraph(Graph* G, char* vexs, int* arcs) {  
    for (int i = 0 ; i < G -> vexNum; i++) {  
        G -> vexs[i] = vexs[i];  
        for (int j = 0; j < G -> vexNum; j++) {  
            G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);  
            if (G -> arcs[i][j] != 0)  
                G -> arcNum ++;  
        }  
    }  
    G -> arcNum /= 2;  
}  
  
void DFS(Graph* G, int* visited, int index) {  
    printf("%c\t", G -> vexs[index]);  
    visited[index] = 1;  
    for (int i = 0; i < G ->vexNum; i++) {  
        if (G -> arcs[index][i] == 1 && !visited[i]) {  
            DFS(G, visited, i);  
        }  
    }  
}  
  
int main() {  
    Graph* G = initGraph(6);  
    int* visited = (int*)malloc(sizeof(int) * G -> vexNum);  
    for (int i = 0; i < G -> vexNum; i++)  
        visited[i] = 0;  
    int arcs[6][6] = {  
        0,1,1,1,0,0,  
        0,0,0,0,0,0,  
        0,1,0,0,1,0,  
        0,0,0,0,1,0,  
        0,0,0,0,0,0,  
        0,0,0,1,1,0  
    };  
    createGraph(G, "123456", (int*)arcs);  
    DFS(G, visited, 0);  
    printf("\n");  
    topologicalSort(G);  
    return 0;  
}

关键路径

#include <stdio.h>  
#include <stdlib.h>  
#define MAX 65535  
  
typedef struct Graph {  
    char* vexs;  
    int** arcs;  
    int vexNum;  
    int arcNum;  
}Graph;  
  
typedef struct Node {  
    int data;  
    struct Node* next;  
}Node;  
  
Node* initStack() {  
    Node* stack = (Node*)malloc(sizeof(Node));  
    stack -> data = 0;  
    stack -> next = NULL;  
    return stack;  
}  
  
int isEmpty(Node* stack) {  
    if (stack -> next == NULL) {  
        return 1;  
    }  
    else {  
        return 0;  
    }  
}  
  
void push(Node* stack, int data) {  
    Node* node = (Node*)malloc(sizeof(Node));  
    node -> data = data;  
    node -> next = stack -> next;  
    stack -> next = node;  
    stack -> data ++;  
}  
  
int pop(Node* stack) {  
    if (!isEmpty(stack)) {  
        Node* node = stack -> next;  
        stack -> next = node -> next;  
        return node -> data;  
    }  
    else {  
        return -1;  
    }  
}  
  
int* findInDegrees(Graph* G) {  
    int* inDegrees = (int*)malloc(sizeof(int) * G -> vexNum);  
    for (int i = 0; i < G -> vexNum; i++) {  
        inDegrees[i] = 0;  
    }  
    for (int i = 0 ; i < G -> vexNum; i++) {  
        for (int j = 0; j < G -> vexNum; j++) {  
            if (G -> arcs[i][j] > 0 && G -> arcs[i][j] != MAX)  
                inDegrees[j] = inDegrees[j] + 1;  
        }  
    }  
    return inDegrees;  
}  
  
int* topologicalSort(Graph* G) {  
    int index = 0;  
    int* top = (int*)malloc(sizeof(int) * G -> vexNum);  
    int* inDegrees = findInDegrees(G);  
    Node* stack = initStack();  
    for (int i = 0 ; i < G -> vexNum; i++) {  
        if (inDegrees[i] == 0) {  
            push(stack, i);  
        }  
    }  
    while (!isEmpty(stack)) {  
        int vex = pop(stack);  
        top[index++] = vex;  
        for (int i = 0 ; i < G -> vexNum; i++) {  
            if (G -> arcs[vex][i] > 0 && G -> arcs[vex][i] != MAX) {  
                inDegrees[i] = inDegrees[i] - 1;  
                if (inDegrees[i] == 0)   
                    push(stack, i);  
            }  
        }  
    }  
    for (int i = 0; i < index; i++) {  
        printf("%c ", G -> vexs[top[i]]);  
    }  
    printf("\n");  
    return top;  
}  
  
Graph* initGraph(int vexNum) {  
    Graph* G = (Graph*)malloc(sizeof(Graph));  
    G -> vexs = (char*)malloc(sizeof(char) * vexNum);  
    G -> arcs = (int**)malloc(sizeof(int*) * vexNum);  
    for (int i = 0 ; i < vexNum; i++) {  
        G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);  
    }  
    G -> vexNum = vexNum;  
    G -> arcNum = 0;  
    return G;  
}  
  
void createGraph(Graph* G, char* vexs, int* arcs) {  
    for (int i = 0 ; i < G -> vexNum; i++) {  
        G -> vexs[i] = vexs[i];  
        for (int j = 0; j < G -> vexNum; j++) {  
            G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);  
            if (G -> arcs[i][j] > 0 && G -> arcs[i][j] != MAX)  
                G -> arcNum ++;  
        }  
    }  
}  
  
void DFS(Graph* G, int* visited, int index) {  
    printf("%c ", G -> vexs[index]);  
    visited[index] = 1;  
    for (int i = 0; i < G ->vexNum; i++) {  
        if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX && !visited[i]) {  
            DFS(G, visited, i);  
        }  
    }  
}  
  
int getIndex(int* top, Graph* G, int i) {  
    int j;  
    for(j = 0; j < G -> vexNum; j++) {  
        if (top[j] == i) {  
            break;  
        }  
    }  
    return j;  
}  
  
void criticalPath(Graph* G) {  
    int* top = topologicalSort(G);  
    int* early = (int*)malloc(sizeof(int) * G -> vexNum);  
    int* late = (int*)malloc(sizeof(int) * G -> vexNum);  
    for (int i = 0; i < G -> vexNum; i++) {  
        early[i] = 0;  
        late[i] = 0;  
    }  
    // 计算最早发生时间  
    for (int i = 0; i < G -> vexNum; i++) {  
        int max = 0;  
        for (int j = 0; j < G -> vexNum; j++) {  
            if (G -> arcs[j][top[i]] > 0 && G -> arcs[j][top[i]] != MAX) {  
                int index = getIndex(top, G, j);  
                if (early[index] + G -> arcs[j][top[i]] > max)  
                    max = early[index] + G -> arcs[j][top[i]];  
            }  
        }  
        early[i] = max;  
    }  
    for (int i = 0; i < G -> vexNum; i++) {  
        printf("%d ", early[i]);  
    }  
    printf("\n");  
    late[(G -> vexNum) - 1] = early[(G -> vexNum) - 1];  
    // 计算最晚发生时间  
    for (int i = (G -> vexNum) - 2; i >= 0; i--) {  
        int min = MAX;  
        for (int j = 0; j < G -> vexNum; j++) {  
            if (G -> arcs[top[i]][j] > 0 && G -> arcs[top[i]][j] != MAX) {  
                int index = getIndex(top, G, j);  
                if (late[index] - G -> arcs[top[i]][j] < min)  
                    min = late[index] - G -> arcs[top[i]][j];  
            }  
        }  
        late[i] = min;  
    }  
    for (int i = 0; i < G -> vexNum; i++) {  
        printf("%d ", late[i]);  
    }  
    printf("\n");  
    for (int i = 0; i < G -> vexNum; i++) {  
        for(int j = 0; j < G -> vexNum; j++) {  
            if (G -> arcs[i][j] > 0 && G -> arcs[i][j] != MAX) {  
                int start = getIndex(top, G, i);  
                int end = getIndex(top, G, j);  
                if ((late[end] - G -> arcs[i][j]) - early[start] == 0) {  
                    printf("start = %d end = %d\n", i, j);  
                }  
            }  
        }  
    }  
}  
  
int main() {  
    Graph* G = initGraph(9);  
    int* visited = (int*)malloc(sizeof(int) * G -> vexNum);  
    for (int i = 0; i < G -> vexNum; i++)  
        visited[i] = 0;  
    int arcs[9][9] = {  
        0, 6, 4, 5, MAX, MAX, MAX, MAX, MAX,  
        MAX, 0, MAX, MAX, 1, MAX, MAX, MAX, MAX,  
        MAX, MAX, 0, MAX, 1, MAX, MAX, MAX, MAX,  
        MAX, MAX, MAX, 0, MAX, 2, MAX, MAX, MAX,  
        MAX, MAX, MAX, MAX, 0, MAX, 9, 7, MAX,  
        MAX, MAX, MAX, MAX, MAX, 0, MAX, 4, MAX,  
        MAX, MAX, MAX, MAX, MAX, MAX, 0, MAX, 2,  
        MAX, MAX, MAX, MAX, MAX, MAX, MAX, 0, 4,  
        MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, 0  
    };  
    createGraph(G, "012345678", (int*)arcs);  
    DFS(G, visited, 0);  
    printf("\n");  
    criticalPath(G);  
    return 0;  
}

排序

顺序查找

二分查找

B树

哈希表

插入排序

希尔排序

冒泡排序

快速排序

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值