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]);
}
}
}
}