数据结构(六)

本文详细介绍了数据结构中的二叉树(顺序存储、链式存储及遍历)、图的存储与遍历(邻接矩阵和邻接表),以及查找算法(顺序查找、折半查找、分块查找和Hash查找)和排序算法(选择排序、插入排序、快速排序和堆排序)。
摘要由CSDN通过智能技术生成

一、复习

二叉树的顺序存储:首先,将二叉树补充成完全二叉树之后,将所有节点从上到下,从左到右依次排序

二叉树的链式存储:

​ 节点定义:

typedef char data_t;
struct node
{
    data_t data;
    struct node *l_child;
    struct node *r_child;
};

二叉树的遍历:

​ 先序、中序、后序遍历

最优二叉树

二、图

1、图的概念

2、图的存储

​ (1)顺序存储 – 邻接矩阵(二维数组)

​ (2)链式存储 – 邻接表(链表)

3、图的遍历

​ (1)深度优先搜索(父子节点)

​ (2)广度优先搜索(兄弟节点)

三、查找

1、顺序查找

2、折半查找

进行折半查找的序列必须是有序的

​ 每一次取当前序列的中间元素跟查找值做比较,比查找值大表示查找数据可能在中间元素的左边

比查找值小表示查找数据可能在中间元素的右边,如果等于查找值,说明找到该元素。

3、分块查找

4、Hash查找

​ 通过装填因子得到Hash表的表长, 找到不大于表长的最大质数p,设计一个Hash函数 pos = key%p

循环将原表中的所有元素带入Hash表达式得到新的Hash表。当产生冲突时,需要解决冲突(线性探查法、链地址法)

四、排序

1、选择排序

​ 升序:将一个序列的第一个元素(标准数)暂定为最小值,将该元素和剩余其他元素比较,找到最小值下标,和标准数交换即可。然后将下一个元素作为标准数,重复之前的操作,直到将序列排序完成。

2、插入排序

​ 原理:将一个无序序列插入到一个有序序列中

​ 升序:从第二个元素开始,将第二个元素跟前面元素做比较,如果比前一个元素小,就继续和前面其他元素比较,直到比完或者 比前面元素时结束插入。 然后继续将第三个元素拿来循环执行前面的操作,直到将所有元素插入完成为止。

3、快速排序

4、堆排序

/*===============================================
*   文件名称:fast_sort.c
*   创 建 者:     
*   创建日期:2023年10月31日
*   描    述:
================================================*/
#include <stdio.h>

void fast_sort(int a[], int low, int high)
{
    int i = low;
    int j = high;
    int x = a[i];
    if(i >= j)
    {
        return;
    }

    while(i < j)
    {
        while(i < j && x < a[j])
        {
            j--;
        }
        a[i] = a[j];
        while(i < j && x > a[i])
        {
            i++;
        }
        a[j] = a[i];
    }
    a[i] = x;
    fast_sort(a, low, i-1);
    fast_sort(a, i+1, high);
}


int main(int argc, char *argv[])
{ 

    int a[7] = {1, 22, 3, 44, 5, 66, 7};
    fast_sort(a, 0, 6);
    for(int i = 0; i < 7; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
} 
/*===============================================
*   文件名称:heap_sort.c
*   创 建 者:     
*   创建日期:2023年10月31日
*   描    述:
================================================*/
#include <stdio.h>

void swap(int *x, int *y)
{
    int tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}


//arr -- 数组首地址   n -- 数组元素个数   i -- 需要维护的根节点下标  
void heapify(int arr[], int n, int i)
{
    int max = i;    //根节点下标
    int l_child = 2*i+1;     //左孩子下标
    int r_child = 2*i+2;     //右孩子下标

    if(l_child < n && arr[max] < arr[l_child])   
    {
        max = l_child;
    }
    if(r_child < n && arr[max] < arr[r_child])
    {
        max = r_child;
    }
    
    if(max != i)
    {
        swap(&arr[i], &arr[max]);
        heapify(arr, n, max);
    }
}

void heap_sort(int arr[], int n)
{
	//创建堆
	for(int i = n/2-1; i>=0; i--)
	{
		heapify(arr, n, i);
	}
	
	//堆排序
	for(int i = n-1; i > 0; i--)
	{
		swap(&arr[i], &arr[0]);
		heapify(arr, i, 0);
	}
}

int main(int argc, char *argv[])
{ 
    int a[7] = {100, 22, -1, 44, 5, 44, 7};
    heap_sort(a, 7);

	for(int i = 0; i < 7; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

    return 0;
} 

serach

/*===============================================
*   文件名称:bin_search.c
*   创 建 者:     
*   创建日期:2024年03月27日
*   描    述:
================================================*/
#include <stdio.h>

int bin_serach(int *a, int len, unsigned int key)
{
    int low = 0;
    int high = len-1;
    int mid;

    while(low <= high)
    {
        mid = (low+high)/2;
        if(a[mid] == key)
        {
            return mid;
        }
        else if(a[mid] < key)
        {
            low = mid+1;
        }
        else
        {
            high = mid-1;
        }
    }
    return -1;

}

int main(int argc, char *argv[])
{ 
    unsigned int a[10] = {1, 3, 11, 24, 39, 40, 42, 55, 87, 101}; 
    unsigned int key;
    int len = sizeof(a)/sizeof(int);
    scanf("%d", &key);
    int ret = bin_serach(a, len, key);
    if(ret == -1)
    {
        printf("序列中没有该key值!\n");
    }
    else
    {
        printf("key值的下标为%d\n", ret);
    }


    return 0;
} 

linktree

/*===============================================
*   文件名称:main.c
*   创 建 者:     
*   创建日期:2024年03月26日
*   描    述:
================================================*/
#include "linktree.h"

int main(int argc, char *argv[])
{ 
	Node *root = Tree_Create();
	//Front_Print(root);
	Level_Print(root);
	printf("\n");
    return 0;
} 
/*===============================================
*   文件名称:linktree.h
*   创 建 者:     
*   创建日期:2024年03月26日
*   描    述:
================================================*/
#ifndef __LINKTREE_H__
#define __LINKTREE_H__

#include <stdio.h>
#include <stdlib.h>

typedef char data_t;
typedef struct node
{
	data_t data;
	struct node *l_child;
	struct node *r_child;
}Node;

Node *Tree_Create(); //创建二叉树

void Front_Print(Node *root); //先序遍历

void Level_Print(Node *root);
void After_Print(Node *root);
void Mid_Print(Node *root);

#endif
/*===============================================
*   文件名称:linktree.c
*   创 建 者:     
*   创建日期:2024年03月26日
*   描    述:
================================================*/
#include "linktree.h"

//创建二叉树
Node *Tree_Create()
{
	char ch;
	scanf("%c", &ch);
	if(ch == '#')
	{
		return NULL;
	}
	
	Node *root = (Node *)malloc(sizeof(Node));
	if(root == NULL)
	{
		printf("malloc failed!\n");
		return NULL;
	}
	
	root->data = ch;
	root->l_child = Tree_Create();
	root->r_child = Tree_Create();	
		
	return root;
}

//先序遍历
void Front_Print(Node *root)
{
	if(NULL == root)
	{
		return;
	}
	
	printf("%c", root->data);  //打印根节点数据
	
	Front_Print(root->l_child);  //打印左孩子
	
	Front_Print(root->r_child);  //打印右孩子
	
}


//中序遍历
void Mid_Print(Node *root)
{
	if(NULL == root)
	{
		return;
	}
		
	Mid_Print(root->l_child);  //打印左孩子
	
	printf("%c", root->data);  //打印根节点数据
	
	Mid_Print(root->r_child);  //打印右孩子
	
}

//后序遍历
void After_Print(Node *root)
{
	if(NULL == root)
	{
		return;
	}
		
	After_Print(root->l_child);  //打印左孩子
		
	After_Print(root->r_child);  //打印右孩子
	
	printf("%c", root->data);  //打印根节点数据
	
}

void Level_Print(Node *root)
{
	Node *buf[50] = {0};
	int front = 0;
	int rear = 1;
	buf[0] = root;
	
	while(front != rear)
	{
		//出队
		printf("%c", buf[front]->data);
		if(buf[front]->l_child != NULL)   //判断出队元素是否有左孩子,如果有则入队
		{ 
			buf[rear] = buf[front]->l_child;
			rear++;   	//队尾下标+1
		}
		if(buf[front]->r_child != NULL)//判断出队元素是否有右孩子,如果有则入队
		{
			buf[rear] = buf[front]->r_child;
			rear++;		//队尾下标+1
		}		
		front++;  		//队头下标+1
	}

}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

磁铁的朋友

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值