知识汇总(数据结构与算法)

目录

1.什么是数据结构

2.线性数据结构

2.1数组

2.2链表

2.3栈

2.4队列

3.树

3.1二叉树

3.2平衡二叉树(AVL树)

3.3哈夫曼树

3.4B树

4.图

4.1图的存储结构

4.2图的遍历

4.21广度优先遍历

4.22深度优先遍历

5.排序

5.1直接插入排序

5.2折半插入排序

5.3希尔排序

5.5冒泡排序

5.6快速排序

5.7简单选择排序

5.8堆排序


1.什么是数据结构

数据结构是具有逻辑关系,应用某种存储结构,封装相应操作的数据元素的集合。数据结构包括逻辑结构、物理结构以及数据的运算和实现。

2.线性数据结构

2.1数组

2.2链表

#include<stdio.h>
#include<stdlib.h>
#define N 10
typedef struct node {
    int data;
    struct node * next;
}ElemNode,*ElemTree;//定义节点

ElemNode* CreatLink(int arr[],int n){
    ElemNode *p, *head, *tail;
    head=NULL;
    for(int i=0;i<n;i++){
        p=(ElemNode*)malloc(sizeof(ElemNode));
        p->data=arr[i];
        p->next=NULL;
        if(head)head=tail=p;
        else tail=tail->next=p;//尾插法:若头部非空则下一个插入p
    }
    return head;
}

void PrintLink(ElemSN * head){
    ElemSN * p;
    for(p=head;p;printf("%3d",p->data),p=p->next);//输出链表
}

int main(void){
    int arr[N];
    ElemSN * head;
    printf("输入要插入的10个元素:");
    for(int i=0;i<N;scanf("%d",&arr[i]),i++);//输入要生成的链表元素,然后i自增
    head = CreatLink(arr,N);
    PrintLink(head);
} 


 

2.3栈

2.31存储结构

·顺序栈的数据结构:

#define MAXSIZE 50  
typedef int ElemType;   
/*两栈共享空间结构*/
typedef struct{
	ElemType data[MAXSIZE];
	int top;	
}Stack;

·链栈的数据结构: 

typedef struct StackNode{
    ElemType data;
    struct StackNode *next;
}StackNode, *LinkStackPrt;
/*构造链栈*/
typedef struct LinkStack{
    LinkStackPrt top;
    int count;
}LinkStack;

2.32应用

递归

2.4队列

2.41存储结构

·顺序队列的数据结构:

#define MAXSIZE 50	
typedef int ElemType;
typedef struct{
	ElemType data[MAXSIZE];	
	int front,rear;
}SqQueue;

·链队列的数据结构:

..

2.42循环队列

·解决了假溢出的问题

·当队首指针Q->front = MAXSIZE-1后,再前进一个位置就自动到0,这可以利用除法取余运算(%)来实现。

3.树

3.1二叉树

·先序遍历:根左右

·中序遍历:左根右

·后序遍历:左右根

#include<stdio.h>
#include<stdlib.h>
//二叉树结点的结构
typedef struct BiTNode
{
      char data;
      struct BiTNode *lchild,*rchild;
  }BiTNode,*BiTree;

//二叉树的先序建立
void CreateBiTree(BiTree *T)
{
      char ch;
      scanf("%c",&ch);
      *T=(BiTree)malloc(sizeof(BiTNode));
      if(!*T)
         exit(-1);
      (*T)->data=ch;
      CreateBiTree(&(*T)->lchild);
      CreateBiTree(&(*T)->rchild);
      
 }

//二叉树的先序遍历
void PreOrderTraverse(BiTree *T)//T指向的地址才是
{
      if(T==NULL)
         return;
      printf("%3c",T->data);
      PreOederTraverse(T->lchild);
      PreOederTraverse(T->rchild);
}

int main(void){
    int arr[N];
    BiTree head;
    printf("输入要插入的元素:");
    CreateBiTree(head);
    PreOrderTraverse(head);
}

3.2二叉查找树(二叉搜索树,二叉排序树)

左子树的值<根节点的值<右子树的值

3.3平衡二叉树(AVL树)

或是一颗空树,或具有以下性质的二叉排序树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1。

//判断该二叉树是否AVL树
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
    int key;
    struct Node *lchild;
    struct Node *rchild;
    int height;
}TreeNode;


int height(struct TreeNode* root){
    if(root==NULL)
       return 0;
    else return fmax(height(root->left),height(root->right))+1;
//返回左右子树最大深度加上根节点
}

bool isBalanced(struct TreeNode* root)
{
     if(root==NULL)
        return true;
     else 
        return fabs(height(root->left)-height(root->right))<=1&&isBalanced(root->left)&&isBalanced(root->right);//fabs是求绝对值

3.3哈夫曼树

3.4B树

平衡多路查找树

4.图

4.1图的存储结构

邻接矩阵--包含一个存储所有顶点的数组成员

邻接表(有向图为十字链表,无向图为邻接多重表)

边集数组

4.2图的遍历

4.21广度优先遍历

4.22深度优先遍历

5.排序

5.1直接插入排序

元素与nums[i]比较若元素小则时nums[i]向后移动否则插入元素

5.2折半插入排序

用二分法进行插入排序

5.3希尔排序

先将待排序列进行gap预排序,使待排序列接近有序,再进行一次插入排序,此时插入排序的时间复杂度为O(N),

5.5冒泡排序

·相邻两个元素进行比较,若逆序则交换,每交换一次无序部分的最后一个将变为有序(即最大);

#include<stdio.h>
#include<stdlib.h>
#define N 10
void BubbleSort(int arr[],int n){
	int i;int j;
	int temp;
	int flag=1;//判断本轮循环是否有元素交换 
    //注意下标溢出!!! 
	for(i=n;i>0&&flag==1;i--)/*大循环flag为0则或循环次数为N-1则停止 
	                            i是循环下标的end,因为i到n都是有序数组*/ 
	for(j=0,flag=0;j<i-1;j++)
	  { 
	    if(arr[j]>arr[j+1]){
		flag=1;//有元素交换
		temp=arr[j];
		arr[j]=arr[j+1];
		arr[j+1]=temp;//交换元素 
	}}//注意下标 
	
} 
int main(void){
	int nums[N];
	for(int i=0;i<N;i++)
	scanf("%d",&nums[i]);
	BubbleSort(nums,N);
	for(int i=0;i<N;i++)
	printf("%d ",nums[i]);
} 

5.6快速排序

·思路:先将数组中第一个元素取出,从后面找到比该元素小的元素再从前找比该元素小的元素两两交换,直到前后下标相同,将该元素与第一个元素交换,然后再将该元素前后的子集进行递归。

·时间复杂度:一次遍历时间复杂度为n,递归层次深度为lgn~n(最好情况是每次key值都在中间,这样就一共lg2n次,最坏情况是每次key值都在第一个,这样层次最深一共n次),总共的时间复杂度为O(nlgn);

#include<stdio.h>
#include<stdlib.h>
#define N 10
void QuickSort(int* arr, int begin, int end)
{   //begin和end是本轮循环中固定的起点和终点 

	int left = begin,right = end;
	int key = arr[begin];//选取第一个元素作为参照 
	while (left < right)
	{
		//先将后面更小的元素放前面key的位置 
		while (arr[right] >= key && left < right)
		{
			right--;
		}
		arr[left] = arr[right];
		//找大
		while (arr[left] <= key && left < right)
		{
			left++;
		}
		//大的放到右边的坑里
		arr[right] = arr[left];
	}
	//因为轮次问题本次轮到执行arr[left]=arr[right] 
	arr[left] = key;
	/*
	key的相对位置已经分好,此后key的位置将固定,
	本轮循环实现了key前面所有元素小于key的后面所有元素大于key
	*/ 
	if(begin<left)
	QuickSort(arr, begin,  left- 1);//注意下标:整个数组开始和结束还是begin和end
	if(right<end) //以key(下标为left)为分界点 
	QuickSort(arr, left+ 1, end);
}
int main(void){
	int nums[N];
	for(int i=0;i<N;i++)
	scanf("%d",&nums[i]);
	QuickSort(nums, 0, N-1);
	for(int i=0;i<N;i++)
	printf("%d ",nums[i]);
} 

5.7简单选择排序

每次选一个最小的元素和无序数组中第一个元素交换

5.8堆排序

·思路:从n/2的节点开始,将非叶子节点与其子节点比较,若根比孩子大/小则交换,再n-1递归执行

·时间复杂度:下沉调整的时间复杂度等同于堆的高度O(logn),构建二叉堆执行下沉调整次数是n/2,循环删除进行下沉调整次数是n-1,时间复杂度约为O(nlogn)

 

5.9归并排序

·思路:归并排序对序列的元素进行逐层折半分组,然后从最小分组开始比较排序,合并成一个大的分组,逐层进行,最终所有的元素都是有序的 

时间复杂度:每次遍历的时间复杂度是O(n),递归次数为O(lgn),总共时间复杂度是O(nlgn)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nvJMNUvk-1592551094228)(./归并1.png)]

5.10基数排序

 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hff8mpfO-1594868673542)(./桶3.png)]

 

5.9比较排序性能:

1.时间性能:

1)O(nlogn):快速排序、堆排序、归并排序

2)O(n^2):直接插入排序、冒泡排序、简单选择排序

3)O(n):基数排序

2.空间性能:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值