数据结构(一):顺序表

1、顺序表

1.1头插

typedef int SLDataType;
//动态顺序表
typedef struct SeqList
{
	SLDataType *a;
	int sz;//表示数组中存放多少数据
	int Capacity;//数组实际容量
}SL;

//增容
void SeqListCheckCapicity(SL* ps)
{
	//如果没有空间或者空间不足,开始扩容
	if (ps->sz == ps->Capacity)
	{
		int NewCapacity = ps->Capacity == 0 ? 4 : ps->Capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, NewCapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("开辟空间失败!\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->Capacity = NewCapacity;
	}
}

//头插
void SeqListPushFront(SL* ps, SLDataType x)
{
	SeqListCheckCapicity(ps);
	int end = ps->sz - 1;
	while (end>=0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->sz++;
}

1.2头删

//头删
void SeqListPopFront(SL* ps)
{
	int begin = 1;
	assert(ps->sz > 0);
	while (begin<ps->sz)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->sz--;
}

1.3尾插

//尾插
void SeqListPushBack(SL* ps, SLDataType x)
{
	SeqListCheckCapicity(ps);
	ps->a[ps->sz] = x;
	ps->sz++;
}

1.4尾删

//尾删
void SeqListPopBack(SL* ps)
{
	//ps->a[ps->sz - 1] = 0;
	if (ps->sz > 0)
	{
		ps->sz--;
	}
}

1.5按数值查找

//按值x查找,找到返回x,找不到返回-1
int SeqListFind(SL* ps, SLDataType x)
{
	assert(ps->sz > 0);
	for (int i = 0; i < ps->sz -1; i++)
	{
		if (ps->a[i]==x)
		{
			return x;
		}
	}
	return -1;
}

1.6按位置插入

//指定位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps->sz > 0);
	if (pos < ps->sz)
	{
		for (int i = pos; i < ps->sz - 1; i++)
		{
			ps->a[i + 1] = ps->a[i];
		}
		ps->a[pos] = x;
	}
	else
	{
		printf("超出查找范围\n");
	}	
}

2.链表

2.1单链表

2.1.1头插

创建链表 /节点

typedef int SLiDataType;

 typedef struct SLTNode
{
	SLiDataType data;
	struct SListNode* next;
}SListNode;
//创建新节点
SListNode* CreateListNode(SLiDataType x)
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}
//头插
void SListPushFront(SListNode** pphead, SLiDataType x)
{
	SListNode* newnode = CreateListNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

2.1.2头删

//头删
void SListPopFront(SListNode** pphead)
{
	if (*pphead == NULL)
	{
		printf("*pphead=null\n");
		return;
	}
	SListNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

2.1.3尾插

//尾插
void SListPushBack(SListNode**pphead, SLiDataType x)
{
	SListNode* newnode = CreateListNode(x);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SListNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

2.1.4尾删

//尾删
void SListPopBack(SListNode** pphead)
{
	SListNode* pre = NULL;
	SListNode* tail = *pphead;
	if (*pphead == NULL)
	{
		return;
	}
	else if((*pphead)->next==NULL)
	{
		free((*pphead)->next);
		*pphead = NULL;
	}
	else
	{
		while (tail->next)
		{
			pre = tail;
			tail = tail->next;
		}
		free(tail->next);
		tail = NULL;
		pre->next = NULL;
	}
}
	

2.1.5查找

//查找
SListNode* SListFind(SListNode* phead, SLiDataType x)
{
	SListNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		else
		{
			cur = cur->next;
		}
	}
	return NULL;
}

2.1.6插入

//插入
void SListInsert(SListNode** pphead, SListNode* pos, SLiDataType x)
{
	SListNode* newnode = CreateListNode(x);
	SListNode* Prepos = *pphead;
	if (*pphead == pos)
	{
		newnode->next = *pphead;
		*pphead = newnode;
	}
	else
	{
		while (Prepos->next != pos)
		{
			Prepos = Prepos->next;
		}
		Prepos->next = newnode;
		newnode->next = pos;
	}
}

2.2双链表 

2.2.1头插

typedef int LTDataType;
typedef struct ListNode
{ 
	LTDataType data;
	struct LTNode* prev;
	struct LTNode* next;

}LTNode;
//头插
void ListPushFront(LTNode* phead, LTDataType x)
{
	LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
	LTNode* pheadNext = phead->next;
	pheadNext = newnode;
	newnode->data = x;
	newnode->next = pheadNext;
	pheadNext->prev = newnode;
	newnode->prev = phead;
}

2.2.2头删

//头删
void ListPopFront(LTNode* phead)
{
	assert(phead);
	assert(phead != phead->next);
	LTNode* next = phead->next;
	LTNode* nextNext = next->next;
	phead->next = nextNext;
	nextNext->prev = phead;
	free(next);
}

2.2.3尾插

//尾插
void ListPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* tail = phead->prev;
	LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
	newnode->data = x;
	tail->next = newnode;
	newnode->prev = tail;
	newnode->next = phead;
	phead->prev = newnode;
}

2.2.4尾删

//尾删
void ListPopBack(LTNode* phead)
{
	assert(phead);
	assert(phead!=phead->next);
	LTNode* tail = phead->prev;
	LTNode* tailPrev = tail->prev;
	free(tail);
	tailPrev->next = phead;
	phead->prev = tailPrev;
}

2.2.5查找

//查找
LTNode* ListFind(LTNode* phead, LTDataType x)
{
	LTNode* cur = phead->next;
	while (cur!=phead)
	{
		if (cur->data ==x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

2.2.6插入

//插入
void ListInsert(LTNode* pos, LTDataType x)
{
	assert(pos);
	LTNode* posPrev = pos->prev;
	LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
	newnode->data = x;
	posPrev->next = newnode;
	newnode->prev = posPrev;
	newnode->next = pos;
	pos->prev = newnode;
}

2.2.7删除 

//删除
void ListErase(LTNode* pos)
{
	assert(pos);
	LTNode* posPrev = pos->prev;
	LTNode* posNext = pos->next;
	posPrev->next = posNext;
	posNext->prev = posPrev;
	free(pos);
	pos = NULL;
}

3、二叉树

3.1二叉树遍历

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef char BinTreeDataType;
typedef struct BinTreeNode
{
	struct BinTreeNode* left;
	struct BinTreeNode* right;
	BinTreeDataType data;
}BTNode;
//前序
void prevOrder(BTNode*root)
{
	if (root == NULL)
	{
		printf(" NULL ");
		return;
	}
	printf(" %c ", root->data);
	prevOrder(root->left);
	prevOrder(root->right);
}
//中序
void midOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf(" NULL ");
		return;
	}
	prevOrder(root->left);
	printf(" %c ", root->data);
	prevOrder(root->right);
}
//后序
void backOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf(" NULL ");
		return;
	}
	prevOrder(root->left);
	prevOrder(root->right);
	printf(" %c ", root->data);
}
//节点个数
void TreeSize(BTNode* root,int*size)
{
	if (root == NULL)
		return;
	(*size)++;
	TreeSize(root->left,size);
	TreeSize(root->right,size);
}
//叶子节点个数
int LeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	else if(root->left==NULL&&root->right==NULL)
	{
		return 1;
	}
	return LeafSize(root->left) + LeafSize(root->right);
}
int main()
{
	BTNode* A = (BTNode*)malloc(sizeof(BTNode));
	A->data = 'A';
	A->left = NULL;
	A->right = NULL;

	BTNode* B = (BTNode*)malloc(sizeof(BTNode));
	B->data = 'B';
	B->left = NULL;
	B->right = NULL;

	BTNode* C = (BTNode*)malloc(sizeof(BTNode));
	C->data = 'C';
	C->left = NULL;
	C->right = NULL;

	BTNode* D = (BTNode*)malloc(sizeof(BTNode));
	D->data = 'D';
	D->left = NULL;
	D->right = NULL;

	BTNode* E = (BTNode*)malloc(sizeof(BTNode));
	E->data = 'E';
	E->left = NULL;
	E->right = NULL;
	A->left = B;
	A->right = C;
	B->left = D;
	B->right = E;
	prevOrder(A);
	int size = 0;
	TreeSize(A,&size);
	printf("\n TreeSize=%d\n", size);
	printf("\n LeafSize=%d\n", LeafSize(A));
	
	return 0;
}

4、排序

4.1插入排序

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//插入排序
void InsertSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int end=i;
		int temp = a[end + 1];
		while (end >= 0)
		{
			if (a[end] > temp)
			{
				a[end+1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = temp;
	}
}
void ArrPrint(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf(" %d ", a[i]);
	}
	printf("\n");
}
void test01()
{
	int a[] = { 2,5,7,4,1,3,9,8,0 };
	int n = sizeof(a) / sizeof(a[0]);
	InsertSort(a, n);
	ArrPrint(a, n);
}
int main()
{
	test01();
	return 0;
}

4.2希尔排序

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void shellSort(int* a, int n)
{	
	int gap=n;
	while (gap>1)
	{
		gap = gap / 2;
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int temp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > temp)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = temp;
		}
	}	
}
void ArrPrint(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf(" %d ", a[i]);
	}
	printf("\n");
}
void test01()
{
	int a[] = { 2,5,7,4,1,3,9,8,0 };
	int n = sizeof(a) / sizeof(a[0]);
	shellSort(a, n);
	ArrPrint(a, n);
}
int main()
{
	test01();
	return 0;
}

4.3选择排序

#define _CRT_SECURE_NO_WARNINGS 1
#include"Sort.h"
void selectSort(int* a, int n)
{
	int begin = 0, end = n - 1;
	while (begin<end)
	{
		int mini = begin;
		int maxi = end;
		for (int i = begin; i <=end; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;
			}
			if (a[i] > a[maxi])
			{
				maxi = i;
			}			
		}
		Swap(&a[begin], &a[mini]);
		if (begin == maxi)
		{
			maxi = mini;
		}
		Swap(&a[end], &a[maxi]);
		begin++;
		end--;
	}
}

4.4堆排序 

#define _CRT_SECURE_NO_WARNINGS 1
#include"Sort.h"
//堆排序
//堆的逻辑结构是一棵完全二叉树;物理结构是数组
//leftchild=parent*2+1
//rightchild=parent*2+2
//parent=(child-1)/2
//大堆:树中所有的父亲都大于等于孩子 
//小堆:树中所有的父亲都小于等于孩子
void Swap(int* p1, int* p2) 
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

//向下调整算法
void adjustDown(int* a, int n,int root)//前提:左右子树都是小堆
{
	int parent = root;
	int child = parent * 2 + 1;//默认是左孩子
	while (child<n)
	{
		//1.选出左右孩子大的那一个
		if (child+1<n && a[child+1] < a[child])
		{
			child += 1;
		}
		if (a[child] < a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
//向下调整算法
void adjustUp(int* a, int n, int root)//前提:左右子树都是小堆
{
	int parent = root;
	int child = parent * 2 + 1;//默认是左孩子
	while (child < n)
	{
		//1.选出左右孩子大的那一个
		if (child + 1 < n && a[child + 1] > a[child])
		{
			child += 1;
		}
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
//堆排序
void heapSort(int* a, int n)
{
	//排升序建大堆
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		adjustUp(a, n, i);
	}
	int end = n - 1;
	while (end>0)
	{
		Swap(&a[0], &a[end]);
		adjustUp(a, end, 0);
		end--;
	}
}

4.5冒泡排序 

#define _CRT_SECURE_NO_WARNINGS 1
#include"Sort.h"
void bubbleSort(int*a, int n)
{
	for (int j = 0; j < n; j++)
	{
		for (int i = 1; i < n-j; i++)
		{
			if (a[i-1] > a[i])
			{
				Swap(&a[i], &a[i - 1]);
			}
		}
	}	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jay-juice

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

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

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

打赏作者

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

抵扣说明:

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

余额充值