数据结构和算法复习

队列

循环队列

循环队列的空和满

如果采用和普通的队列一样的处理方式,比如front和rear都指向实际元素的位置,就会出现判空和判满一样的
处理方式一般是空一个元素,然后让rear指向实际队尾的下一个元素

Q.font == Q.rear;//空   
(Q.rear + 1) % Q.length == Q.front;

串数组和广义表

子串的个数

  1. 子串: n(n+1)/2 + 1
  2. 非空子串:n(n+1)/2
  3. 非空真子串:n(n+1)/2 - 1

理解:就是n个一个字符的子串,n-1个两个字符的子串,以此类推, 到最后一个相等的子串,就是非真子串,就是n(n+1)/2个,最后加上一个空子串。

二叉树

二叉树的结构

typedef struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}

二叉树的性质

  1. 二叉树第i层最多有2i-1
    树的下一层的个数是上一层的两倍
  2. 深度为k的二叉树至多有2k - 1个节点
  3. 度为0的节点个数等于度为2的节点个数+1 n0 = n2 + 1;

完全二叉树的性质

完全二叉树就是满二叉树少了最右边的几个节点

  1. 有n个节点的完全二叉树的深度是log2n + 1,向下取整
  2. 2i是节点的左孩子2i+1是右孩子

树和二叉树

如果将一个树转化成二叉树,用二叉链表的形式存储,那么根节点的右指针就是空

huffmanTree 哈夫曼树

哈夫曼树是前缀编码,就是任何一个编码都不是其他编码的前缀

其他

先序后序和中序的叶子节点的位置都一样

有向完全图的弧的个数为n(n - 1);

图的一些性质

强连通图就是有向图的最小连通分量

图的结构

邻接矩阵

typedef struct{
  char vexs[MVNum];           //存放顶点的一维数组
  int arcs[MVNum][MVNum];     //邻接矩阵
  int vexnum,arcnum;          //图的当前顶点数和边数
}MGraph;

邻接表

typedef struct ArcNode{                        //表结点
    int adjvex;                                    //邻接点的位置
    struct ArcNode *nextarc;      //指向下一个表结点的指针
  }ArcNode;
typedef struct VNode{
   char data;                                    //顶点信息
   ArcNode *firstarc;         //指向第一个表结点的指针
}VNode, AdjList[MVNum];                 //AdjList表示邻接表类型
typedef struct{
    AdjList vertices;              //头结点数组
    int vexnum, arcnum;     //图的当前顶点数和边数
}ALGraph;

图的应用

  1. 拓扑序列 就是从没有前驱的开始输出,有前驱的就不能输出 一般可以用拓扑序列来判断是否成环

排序

插入排序

直接插入排序

#include <stdio.h>
typedef int DataType;                                // 定义具体数据类型

#define LISTSIZE 100                                // LISTSIZE 表示顺序表可能的最大数据元素数目

/****** 顺序表存储结构 ******/
typedef struct
{
	DataType list[LISTSIZE];
	int length;
}SqList;


/****** 初始化顺序表 ******/
int InitList(SqList *L)                // L为指向顺序表的指针
{
	L->length = 0;            
	return 1;
}

/****** 求顺序表表长 ******/
int ListLenth(SqList L)                // L为顺序表
{
	return L.length;        
}

/****** 判断顺序表是否为空 ******/
int ListEmpty(SqList L)                // L为顺序表
{
	if (L.length <= 0)        
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

/****** 向顺序表插入元素 ******/
int ListInsert(SqList *L, int pos, DataType item)
{                                    // L为指向顺序表的指针,pos为插入位置,item为待插入的数据元素
	int i;
	
	if (L -> length >= LISTSIZE)    // 判断顺序表是否已满
	{                                
		printf("顺序表已满,无法插入\n");
		return 0;
	}
	
	if (pos <= 0 || pos > L -> length + 1)
	{                                // 检查元素插入位置是否在顺序表里
		printf("插入位置不合法\n");
		return 0;
	}
	
	for (i = L -> length - 1; i >= pos - 1; i--)
	{                                // 移动数据元素
		L -> list[i + 1] = L -> list[i];
	}
	
	L -> list[pos - 1] = item;        // 插入元素
	L -> length++;                    // 表长加一
	
	return 1;
}


/****** 遍历顺序表 ******/
int TraverList(SqList L)            // L为顺序表
{                        
	int i;
	for(i = 0; i < L.length; i++)
	{
		printf("%d ", L.list[i]);
	}
	printf("\n");
	return 1;
}
void InsertSort(SqList *L);
int main()
{
	SqList L;
	DataType x;
	char ch;
	int pos = 1;
	InitList(&L);
	do
	{  
		scanf("%d",&x);
		ListInsert( &L , pos++ , x );        
	}while ((ch=getchar())!='\n');
	InsertSort(&L);
	printf("The sorted List is\n");
	TraverList(L);
	return 0;
}

void InsertSort(SqList *L){
	int j;
	int temp;
	for(int i = 1; i < L->length; i++){
		if(L->list[i] < L->list[i - 1]){
			temp = L->list[i];
			L->list[i] = L->list[i - 1];
			for(j = i - 1; j > 0; j--){
				if(L->list[j - 1] > temp){
					L->list[j] = L->list[j - 1];
				}
				else{
					L->list[j] = temp;
					break;
				}
			}
			if(j == 0){
				L->list[0] = temp;
			}
		}
		TraverList(*L);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值