期末不知道如何复习数据结构的话,不妨点进来看看。看明白保你过。

简介: 期末不知道如何复习数据结构的话,不妨点进来看看。看明白保你过。

顺序表


这个是动态顺序表,我觉得功能已经十分的齐全了,要是有缺少的功能大家可以私信或者在评论区告诉我,我会修改的。


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLDatatype;
typedef struct SeqList
{
  SLDatatype* a;
  int size;//储存的有效数据个数
  int capacity;//容量
}SL;
void SLInit(SL* psl)
{
  assert(psl);
  psl->a = (SLDatatype*)malloc(sizeof(SLDatatype)*4);
  if (psl->a == NULL)
  {
  perror("malloc fail");
  return;
  }
  psl->size = 0;
  psl->capacity = 4;
}
void SLCheckCapacity(SL* psl)
{
  assert(psl);
  if (psl->size == psl->capacity)
  {
  SLDatatype* tmp = (SLDatatype*)realloc(psl->a,sizeof(SLDatatype) * psl->capacity * 2);
  if (tmp == NULL)
  {
    perror("realloc fail");
    return;
  }
  psl->a = tmp;
  psl->capacity *= 2;
  }
}
void SLDestroy(SL* psl)
{
  assert(psl);
  free(psl->a);
  psl->a = NULL;
  psl->size = 0;
  psl ->capacity = 0;
}
void SLPrint(SL* psl)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
  printf("%d ", psl->a[i]);
  }
  printf("\n");
}
//STL命名风格
void SLPushBack(SL* psl, SLDatatype x)
{
  assert(psl);
  SLCheckCapacity(psl);
  psl->a[psl->size++] = x;
}
void SLPushFront(SL* psl, SLDatatype x)
{
  assert(psl);
  SLCheckCapacity(psl);
  int end = psl->size-1;
  while (end >= 0)
  {
  psl->a[end + 1] = psl->a[end];
  --end;
  }
  psl->a[0] = x;
  psl->size++;
}
void SLPopBack(SL* psl)
{
  assert(psl);
  if (psl->size <= 0)
  {
  return;
  }
  psl->size--;
}
void SLPopFront(SL* psl)
{
  assert(psl);
  if (psl->size <= 0)
  {
  return;
  }
  for (int i = 0; i < psl->size-1; i++)
  {
  psl->a[i] = psl->a[i + 1];
  }
  psl->size--;
}
void SLInsert(SL* psl, int pos, SLDatatype x)
{
  assert(psl);
  SLCheckCapacity(psl);;
  for (int i = pos; i < psl->size; i++)
  {
  psl->a[i+1] = psl->a[i];
  }
  psl->a[pos] = x;
  psl->size++;
}
void SLErase(SL* psl, int pos)
{
  assert(psl);
  if (psl->size <= 0)
  {
  return;
  }
  for (int i = pos; i < psl->size-1; i++)
  {
  psl->a[i] = psl->a[i + 1];
  }
  psl->size--;
}
// 找到返回下标,没有找到返回-1
int SLFind(SL* psl, SLDatatype x)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
  if (psl->a[i] == x)
  {
    return i;
  }
  }
  return -1;
}
void SLModify(SL* psl, int pos, SLDatatype x)
{
  assert(psl);
  psl->a[pos] = x;
}
void menu()
{
  printf("***************************************\n");
  printf("1、尾插数据  2、尾删数据\n");
  printf("3、头插数据  4、头删数据\n");
  printf("5、打印数据  6.修改数据\n");
  printf("-1.退出程序\n");
  printf("***************************************\n");
}
int main()
{
  int option = 0;
  SL s;
  SLInit(&s);
  while (option != -1)
  {
  menu();
  printf("请输入你的操作:>");
  scanf("%d", &option);
  if (option == 1)
  {
    /*printf("请输入要尾插的数据,以-1结束:");
    int x = 0;
    scanf("%d", &x);
    while (x != -1)
    {
    SLPushBack(&s, x);
    scanf("%d", &x);
    }*/
    int n = 0;
    printf("请输入要尾插的数据个数,再依次输入要插入的数据:");
    scanf("%d", &n);
    int x = 0;
    while (n > 0)
    {
    scanf("%d", &x);
    SLPushBack(&s, x);
    n--;
    }
  }
  else if (option == 5)
  {
    SLPrint(&s);
  }
  else if (option == 2)
  {
    int n = 0;
    printf("请输入要尾删的数据个数");
    scanf("%d", &n);
    int x = 0;
    while (n > 0)
    {
    SLPopBack(&s);
    n--;
    }
  }
  else if (option == 3)
  {
    int n = 0;
    printf("请输入要头插的数据个数,再依次输入要插入的数据:");
    scanf("%d", &n);
    int x = 0;
    while (n > 0)
    {
    scanf("%d", &x);
    SLPushFront(&s, x);
    n--;
    }
  }
  else if (option == 4)
  {
    int x;
    int n;
    printf("请输入需要头删的个数");
    scanf("%d", &n);
    while (n)
    {
    SLPopFront(&s);
    n--;
    }
  }
  else if (option == 6)
  {
    printf("请输入要修改的数的下标\n");
    int x;
    scanf("%d", &x);
    printf("请输入修改后的数字\n");
    int n;
    scanf("%d", &n);
    SLModify(&s, x, n);
  }
  else if (option == -1)
  {
    break;
  }
  else
  {
    printf("无此选项,请重新输入\n");
  }
  }
  SLDestroy(&s);
  return 0;
}


单链表


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDataType;
typedef struct SListNode
{
  SLTDataType data;
  struct SListNode* next;
}SLTNode;
void SLTPrint(SLTNode* phead)
{
  SLTNode* cur = phead;
  while (cur != NULL)
  {
  printf("%d=>", cur->data);
  cur = cur->next;
  }
  printf("NULL");
  printf("\n");
}
SLTNode* BuyLTNode(SLTDataType x)
{
  SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
  if (newnode == NULL)
  {
  perror("malloc fail");
  return NULL;
  }
  newnode->data = x;
  newnode->next = NULL;
  return newnode;
}
void SLPushFront(SLTNode** pphead, SLTDataType x)
{
  SLTNode* newnode = BuyLTNode(x);
  if (*pphead == NULL)
  {
  *pphead = newnode;
  }
  else
  {
  newnode->next = *pphead;
  *pphead = newnode;
  }
}
void SLPushBack(SLTNode** pphead, SLTDataType x)
{
  SLTNode* cur = *pphead;
  SLTNode* newnode = BuyLTNode(x);
  if (*pphead == NULL)
  {
  *pphead = newnode;
  newnode = *pphead;
  }
  else
  {
  while (cur->next!= NULL)
  {
    cur = cur->next;
  }
  cur->next = newnode;
  }
}
void SLPopFront(SLTNode** pphead)
{
  assert(*pphead);
  SLTNode* del = *pphead;
  *pphead = (*pphead)->next;
  free(del);
}
void SLPopBack(SLTNode** pphead)
{
  assert(*pphead);
  if ((*pphead)->next == NULL)
  {
  free(*pphead);
  *pphead = NULL;
  }
  else
  {
  SLTNode* tail = *pphead;
  // 找到尾结点
  while (tail->next->next)
  {
    tail = tail->next;
  }
  free(tail->next);
  tail->next = NULL;
  }
}
void TestSList2()
{
  SLTNode* plist = NULL;
  SLPushBack(&plist, 1);
  SLPushBack(&plist, 2);
  SLPushBack(&plist, 3);
  SLPushBack(&plist, 4);
  SLPopFront(&plist);
  SLPushFront(&plist, 1);
  SLPopBack(&plist);
  SLPushBack(&plist, 4);
  SLTPrint(plist);
}
int main()
{
  TestSList2();
  return 0;
}


双向链表


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int LTDataType;
typedef struct ListNode
{
  struct ListNode* prev;
  struct ListNode* next;
  LTDataType data;
}LTNode;
LTNode* BuyLTNode(LTDataType x)
{
  LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
  if (newnode == NULL)
  {
  perror("malloc fail");
  return NULL;
  }
  newnode->data = x;
  newnode->next = NULL;
  newnode->prev = NULL;
  return newnode;
}
LTNode* LTInit()
{
  LTNode* phead = BuyLTNode(-1);
  phead->next = phead;
  phead->prev = phead;
  return phead;
}
void LTPrint(LTNode* phead)
{
  assert(phead);
  printf("GUard<==>");
  LTNode* cur = phead->next;
  while (cur != phead)
  {
  printf("%d<==>", cur->data);
  cur = cur->next;
  }
  printf("\n");
}
bool LTEmpty(LTNode* phead)
{
  assert(phead);
  return phead->next == phead;
}
void LTPushBack(LTNode* phead, LTDataType x)
{
  assert(phead);
  LTNode* tail = phead->prev;
  LTNode* newnode = BuyLTNode(x);
  newnode->next = phead;
  phead->prev = newnode;
  newnode->prev = tail;
  tail->next = newnode;
}
void LTPushFront(LTNode* phead, LTDataType x)
{
  assert(phead);
  LTNode* head = phead->next;
  LTNode* newnode = BuyLTNode(x);
  phead->next = newnode;
  newnode->prev = phead;
  newnode->next = head;
  head->prev = newnode;
}
void LTPopBack(LTNode* phead)
{
  assert(phead);
  assert(!LTEmpty(phead));
  LTNode* tail = phead->prev;
  LTNode* tailprev = tail->prev;
  free(tail);
  phead->prev = tailprev;
  tailprev->next = phead;
}
void LTPopFront(LTNode* phead)
{
  LTNode* head = phead->next;
  LTNode* headnext = head->next;
  phead->next = headnext;
  headnext->prev = phead;
  free(head);
}
LTNode* LTFind(LTNode* phead, LTDataType x)
{
  LTNode* cur = phead->next;
  while (cur!=phead)
  {
  if (cur->data == x)
  {
    return cur;
  }
  cur = cur->next;
  }
  return NULL;
}
// 在pos之前插入
void LTInsert(LTNode* pos, LTDataType x)
{
  assert(pos);
  LTNode* prev = pos->prev;
  LTNode* newnode = BuyLTNode(x);
  newnode->next = pos;
  pos->prev = newnode;
  prev->next = newnode;
  newnode->prev = prev;
}
// 删除pos位置的值
void LTErase(LTNode* pos)
{
  assert(pos);
  LTNode* posPrev = pos->prev;
  LTNode* posNext = pos->next;
  posPrev->next = posNext;
  posNext->prev = posPrev;
}
void LTDestroy(LTNode* phead)
{
  assert(phead);
  LTNode* cur = phead->next;
  while (cur!=phead)
  {
  LTNode* next = cur->next;
  free(cur);
  cur = next;
  }
  free(phead);
}
void TestList3()
{
  LTNode* plist = LTInit();
  LTPushFront(plist, 1);
  LTPushFront(plist, 2);
  LTPushFront(plist, 3);
  LTPushFront(plist, 4);
  LTPrint(plist);
  LTNode* pos = LTFind(plist, 3);
  if (pos)
  {
  LTInsert(pos, 30);
  }
  LTPopFront(plist);
  LTPopBack(plist);
  LTPushBack(plist, 9);
  LTPrint(plist);
  LTDestroy(plist);
  plist = NULL;
}
int main()
{
  TestList3();
  return 0;
}


像头插,尾删这样的功能,我们可以直接通过复用 LTInsert和LTErase来实现,这样写可以大幅度简化代码,让代码精简。代码如下:


#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct Node
{
  int data;
  struct Node* next;
  struct Node* prev;
}Node;
Node* BuyListNode(int x);
Node* SLInit();
void LTPopFront(Node* phead);
void LTPushFront(Node* phead, int x);
void LTPopBack(Node* phead);
void LTDestroy(Node* phead);
void LTPushBack(Node* phead, int x);
void LTErase(Node* phead);
void LTInsert(Node* pos, int x);
int LTEmpty(Node* phead);
void Print(Node* phead);
Node* BuyListNode(int x)
{
  Node* newnode = (Node*)malloc(sizeof(Node));
  newnode->data = x;
  newnode->next = NULL;
  newnode->prev = NULL;
  return newnode;
}
Node* SLInit()
{
  Node* phead = BuyListNode(-1);
  phead->next = phead;
  phead->prev = phead;
  return phead;
}
void LTInsert(Node* pos, int x)
{
  assert(pos);
  Node* newnode = BuyListNode(x);
  Node* prev = pos->prev;
  newnode->next = prev->next;
  newnode->prev = prev;
  prev->next = newnode;
  pos->prev = newnode;
}
void LTPushFront(Node* phead, int x)
{
  assert(phead);
  LTInsert(phead->next, x);
}
void LTPushBack(Node* phead, int x)
{
  assert(phead);
  LTInsert(phead, x);
}
void LTPopFront(Node* phead)
{
  assert(phead);
  assert(!LTEmpty(phead));
  LTErase(phead->prev);
}
void LTErase(Node* pos)
{
  assert(pos);
  Node* prev = pos->prev;
  Node* next = pos->next;
  prev->next = next;
  next->prev = prev;
}
void LTPopBack(Node* phead)
{
  assert(phead);
  assert(!LTEmpty(phead));
  LTErase(phead->prev);
}
void LTDestroy(Node* phead)
{
  assert(phead);
  Node* cur = phead->next;
  while (phead != cur)
  {
  Node* next = cur->next;
  free(cur);
  cur = next;
  }
  free(phead);
}
int LTEmpty(Node* phead)
{
  assert(phead);
  return phead == phead->next;
}
void Print(Node* phead)
{
  Node* cur = phead->next;
  while (cur != phead)
  {
  Node* next = cur->next;
  printf("%d<==>", cur->data);
  cur = next;
  }
  printf("\n");
}


循环双向链表


typedef int DLLData;
typedef struct DLLNode
{
  DLLData data;
  struct ListNode* next;
  struct ListNode* prev;
}ListNode;
// 创建返回链表的头结点.
ListNode* ListCreate()
{
  ListNode* guard = (ListNode*)malloc(sizeof(ListNode));
  guard->next = guard->prev = guard;
  return guard;
}
// 创建一个新的结点
ListNode* BuyNewnode(LTDataType x)
{
  ListNode* new_node = (ListNode*)malloc(sizeof(ListNode));
  new_node->data = x;
  return new_node;
}
// 双向链表销毁
void ListDestroy(ListNode* phead)
{
  assert(phead);
  ListNode* tmp = phead->next, *node = phead->next;
  phead->next = NULL;
  while (tmp)
  {
  node = tmp->next;
  free(tmp);
  tmp = node;
  }
}
// 双向链表打印
void ListPrint(ListNode* phead)
{
  assert(phead);
  ListNode* tmp = phead->next;
  printf("phead<=>");
  while (tmp != phead)
  {
  printf("%d<=>", tmp->data);
  tmp = tmp->next;
  }
  printf("phead\n");
}
// 双向链表尾插
void ListPushBack(ListNode* phead, LTDataType x)
{
  assert(phead);
  ListInsert(phead, x);
}
// 双向链表尾删
void ListPopBack(ListNode* phead)
{
  assert(phead);
  assert(!CheckVoid(phead));
  ListErase(phead->prev);
}
// 双向链表头插
void ListPushFront(ListNode* phead, LTDataType x)
{
  assert(phead);
  ListInsert(phead->next, x);
}
// 双向链表头删
void ListPopFront(ListNode* phead)
{
  assert(phead);
  assert(!CheckVoid(phead));
  ListErase(phead->next);
}
// 双向链表查找
ListNode* ListFind(ListNode* phead, LTDataType x)
{
  assert(phead);
  ListNode* tmp = phead->next;
  while (tmp != phead)
  {
  if (tmp->data == x)
    return tmp;
  tmp = tmp->next;
  }
  return NULL;
}
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x)
{
  ListNode* front = pos->prev;
  ListNode* new_node = BuyNewnode(x);
  front->next = new_node;
  new_node->next = pos;
  pos->prev = new_node;
  new_node->prev = front;
}
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
  pos->prev->next = pos->next;
  pos->next->prev = pos->prev;
  free(pos);
}
// 检查链表为空
bool CheckVoid(ListNode* rhs)
{
  assert(rhs);
  return rhs->next == rhs;
}



#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack
{
  STDataType* a;
  int top;
  int capacity;
}ST;
void STInit(ST* pst)
{
  assert(pst);
  pst->a = NULL;
  pst->top = 0;//这里要注意,如果设置top为-1,则为指向数据位置,如果设置top=0,则指向数据的下一个位置。
  pst->capacity = 0;
}
bool STEmpty(ST* pst)
{
  assert(pst);
  return pst->top == 0;
}
void STDestroy(ST* pst)
{
  assert(pst);
  free(pst->a);
  pst->a = NULL;
  pst->top = pst->capacity = 0;
}
void STPush(ST* pst, STDataType x)
{
  if (pst->top == pst->capacity)
  {
  int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
  STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);
  if (tmp == NULL)
  {
    perror("realloc fail");
    return;
  }
  pst->a = tmp;
  pst->capacity = newcapacity;
  }
  pst->a[pst->top] = x;
  pst->top++;
}
void STPop(ST* pst)
{
  assert(pst);
  assert(!STEmpty(pst));
  pst->top--;
}
STDataType STTop(ST* pst)
{
  assert(pst);
  assert(!STEmpty(pst));
  return pst->a[pst->top - 1];
}
int STSize(ST* pst)
{
  assert(pst);
  return pst->top;
}
void TestStack1()
{
  ST st;
  STInit(&st);
  STPush(&st, 1);
  STPush(&st, 2);
  printf("%d ", STTop(&st));
  STPop(&st);
  STPush(&st, 3);
  STPush(&st, 4);
  while (!STEmpty(&st))
  {
  printf("%d ", STTop(&st));
  STPop(&st);
  }
  STDestroy(&st);
}
int main()
{
  TestStack1();
  return 0;
}


队列


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{
  QDataType data;
  struct QueueNode* next;
}QNode;
typedef struct Queue
{
  QNode* phead;
  QNode* ptail;
  int size;
}Queue;
void QueueInit(Queue* pq)
{
  assert(pq);
  pq->phead = NULL;
  pq->ptail = NULL;
  pq->size = 0;
}
bool QueueEmpty(Queue* pq)
{
  assert(pq);
  return pq->size == 0;
}
void QueueDestroy(Queue* pq)
{
  assert(pq);
  QNode* cur = pq->phead;
  while (cur)
  {
  QNode* next = cur->next;
  free(cur);
  cur = next;
  }
  pq->ptail = pq->phead = NULL;
  pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x)
{
  assert(pq);
  QNode* newnode = (QNode*)malloc(sizeof(QNode));
  if (newnode == NULL)
  {
  perror("malloc fail");
  return;
  }
  newnode->data = x;
  newnode->next = NULL;
  if (pq->ptail == NULL)
  {
  assert(pq->phead == NULL);
  pq->ptail = pq->phead = newnode;
  }
  else
  {
  pq->ptail->next = newnode;
  pq->ptail = newnode;
  }
  pq->size++;
}
void QueuePop(Queue* pq)
{
  assert(pq);
  assert(!QueueEmpty(pq));
  if (pq->phead->next == NULL)
  {
  free(pq->phead);
  pq->phead = pq->ptail = NULL;
  }
  else
  {
  //头删
  QNode* next = pq->phead->next;
  free(pq->phead);
  pq->phead = next;
  }
  pq->size--;
}
QDataType QueueFront(Queue* pq)
{
  assert(pq);
  assert(!QueueEmpty(pq));
  return pq->phead->data;
}
QDataType QueueBack(Queue* pq)
{
  assert(pq);
  assert(!QueueEmpty(pq));
  return pq->ptail->data;
}
int QueueSize(Queue* pq)
{
  assert(pq);
  return pq->size;
}
int main()
{
  Queue* pq = (Queue*)malloc(sizeof(Queue));;
  QueueInit(pq);
  QueuePush(pq, 1);
  QueuePush(pq, 2);
  QueuePush(pq, 3);
  QueuePush(pq, 4);
  QueuePush(pq, 5);
  printf("%d\n", QueueSize(pq));
  printf("%d\n", QueueFront(pq));
  printf("%d\n", QueueBack(pq));
  return 0;
}


循环队列


# include<stdio.h>
# include<malloc.h>
# define TRUE 1
# define FALSE 0
/*链队列*/
/*链队列的存储结构*/
typedef struct Node {
  int data;      //队列数据域
  struct Node* next;    //队列指针域
}LinkQueueNode;
typedef struct {
  LinkQueueNode* front;//头指针
  LinkQueueNode* rear;//尾指针
}LinkQueue;
/*链队列的初始化*/
int InitQueue(LinkQueue* Q) {
  Q->front = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
  if (Q->front != NULL) {
  Q->rear = Q->front;
  Q->front->next = NULL;
  return TRUE;
  }
  else
  return FALSE;    //溢出
}
/*链队列的创建*/
void CreateQueue(LinkQueue* Q) {
  LinkQueueNode* NewNode;
  int c, flag = 1;
  while (flag) {
  scanf("%d", &c);
  if (c != 0) {
    NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    NewNode->data = c;
    Q->rear->next = NewNode;  //新结点插入到队尾
    Q->rear = NewNode;    //修改队尾指针
  }
  else {
    flag = 0;
    NewNode->next = NULL;
  }
  }
}
/*链队列入队*/
int EnterQueue(LinkQueue* Q, int x) {
  /*将数据元素x插入到队列Q中*/
  LinkQueueNode* NewNode;
  NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
  if (NewNode != NULL) {
  NewNode->data = x;
  NewNode->next = NULL;
  Q->rear->next = NewNode;  //新结点插入到队尾
  Q->rear = NewNode;    //修改队尾指针
  return TRUE;
  }
  return FALSE;
}
/*链队列出队*/
int DeleteQueue(LinkQueue* Q, int* x) {
  /*将队列Q的队头元素出队,并保存到x中*/
  LinkQueueNode* p;
  if (Q->front == Q->rear)  //空队列
  return FALSE;
  p = Q->front->next;    //p指向队头元素
  Q->front->next = p->next;  //队头元素p出队
  if (Q->rear == p)    //若队中只有一个元素p,则p出队后成为空队
  Q->rear = Q->front;
  *x = p->data;
  free(p);
  return TRUE;
}
/*队列输出*/
void Display(LinkQueue* Q) {
  if (Q->front == Q->rear)  //空队列
  printf("空队列!\n");
  else {
  LinkQueueNode* p;
  p = Q->front->next;   //p指向队头元素
  while (p != NULL) {
    printf("%d ", p->data);
    p = p->next;
  }
  printf("\n");
  }
}
int main() {
  int x;
  LinkQueue Q;
  InitQueue(&Q);      //初始化队列
  printf("创建队列(以0结束):");  //创建
  CreateQueue(&Q);
  printf("创建的队列元素为:");
  Display(&Q);
  EnterQueue(&Q, 5);    //入队
  printf("入队后队中元素为:");
  Display(&Q);
  DeleteQueue(&Q, &x);    //出队
  printf("出队元素为:%d\n", x);
  printf("出队后队中元素为:");
  Display(&Q);
  return 0;
}


二叉树


二叉树的层序遍历需要用到队列的知识,大家看代码可能不理解是什么意思,不过没关系。


只要你画个图,一切就会豁然开朗!


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int BTDataType;
typedef struct BinaryTreeNode
{
  BTDataType data;
  struct BinaryTreeNode* left;
  struct BinaryTreeNode* right;
}BTNode;
typedef BTNode* QDataType;
typedef struct QueueNode
{
  struct QueueNode* next;
  QDataType data;
}QNode;
typedef struct Queue
{
  QNode* phead;
  QNode* ptail;
  int size;
}Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
BTNode* BuyNode(BTDataType x)
{
  BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
  if (newnode == NULL)
  {
  perror("malloc fail");
  return NULL;
  }
  newnode->data = x;
  newnode->left = NULL;
  newnode->right = NULL;           
  return newnode;
}
void PrevOrder(BTNode* root)
{
  if (root == NULL)
  {
  printf("NULL ");
  return;
  }
  printf("%d ", root->data);
  PrevOrder(root->left);
  PrevOrder(root->right);
}
void InOrder(BTNode* root)
{
  if (root == NULL)
  {
  printf("NULL");
  return;
  }
  InOrder(root->left);
  printf("%d ", root->data);
  InOrder(root->right);
}
void PostOrder(BTNode* root)
{
  if (root == NULL)
  {
  printf("NULL ");
  return;
  }
  PostOrder(root->left);
  PostOrder(root->right);
  printf("%d ", root->data);
}
int BTNodeSize(BTNode* root)
{
  return root == NULL ? 0 : BTNodeSize(root->left) + BTNodeSize(root->right) + 1;
}
int BTreeLeafSize(BTNode* root)
{
  if (root == NULL)
  {
  return 0;
  }
  if (root->left == NULL && root->right == NULL)
  {
  return 1;
  }
  return BTreeLeafSize(root->left) + BTreeLeafSize(root->right);
}
int BTreeHeight(BTNode* root)
{
  if (root == NULL)
  {
  return 0;
  }
  int LeftHeight = BTreeHeight(root->left);
  int RightHeight = BTreeHeight(root->right);
  return LeftHeight > RightHeight ? LeftHeight + 1 : RightHeight + 1;
}
int BTreeLevelKSize(BTNode* root, int k)
{
  assert(k > 0);
  if (root == NULL)
  {
  return 0;
  }
  if (k == 1)
  {
  return 1;
  }
  return BTreeLevelKSize(root->left, k - 1) + BTreeLevelKSize(root->right, k - 1);
}
BTNode* BTFind(BTNode* root, BTDataType x)
{
  if (root == NULL)
  {
  return NULL;
  }
  if (root->data == x)
  {
  return root;
  }
  BTNode* ret1 = BTFind(root->left, x);
  if (ret1)
  {
  return ret1;
  }
  BTNode* ret2 = BTFind(root->right, x);
  if (ret2)
  {
  return ret2;
  }
  return NULL;
}
void BTreeNodeDestroy(BTNode* root)
{
  if (root == NULL)
  {
  return;
  }
  BTreeNodeDestroy(root->left);
  BTreeNodeDestroy(root->right);
  free(root);
}
// 判断二叉树是否是完全二叉树
bool BTreeComplete(BTNode* root)
{
  Queue q;
  QueueInit(&q);
  if (root)
  QueuePush(&q, root);
  while (!QueueEmpty(&q))
  {
  BTNode* front = QueueFront(&q);
  QueuePop(&q);
  // 遇到空就跳出
  if (front == NULL)
    break;
  QueuePush(&q, front->left);
  QueuePush(&q, front->right);
  }
  // 检查后面的节点有没有非空
  // 有非空,不是完全二叉树
  while (!QueueEmpty(&q))
  {
  BTNode* front = QueueFront(&q);
  QueuePop(&q);
  if (front)
  {
    QueueDestroy(&q);
    return false;
  }
  }
  QueueDestroy(&q);
  return true;
}
void InsertSort(int* a, int n)
{
  for (int i = 1; i < n; ++i)
  {
  // [0, end] 有序,插入tmp依旧有序
  int end = i - 1;
  int tmp = a[i];
  while (end >= 0)
  {
    if (a[end] > tmp)
    {
    a[end + 1] = a[end];
    --end;
    }
    else
    {
    break;
    }
  }
  a[end + 1] = tmp;
  }
}


图的知识太多了,我在这里就不列举了。


大家期末加油。。。祝大家拿满绩。。。


相关文章
|
5月前
|
存储 安全 Java
【C++】引用之带你“消除”C语言版数据结构教材的一些困惑(虽然是C++的内容,但是强烈建议正在学习数据结构的同学点进来看看)
【C++】引用之带你“消除”C语言版数据结构教材的一些困惑(虽然是C++的内容,但是强烈建议正在学习数据结构的同学点进来看看)
41 0
|
10月前
|
存储 机器学习/深度学习 人工智能
【开卷数据结构 】图的基本介绍,不进来看看吗?
【开卷数据结构 】图的基本介绍,不进来看看吗?
133 1
|
7天前
|
机器学习/深度学习 算法 测试技术
【单调栈】3113. 边界元素是最大值的子数组数目
【单调栈】3113. 边界元素是最大值的子数组数目
|
16小时前
|
存储 NoSQL C语言
数据结构——顺序栈与链式栈的实现-2
数据结构——顺序栈与链式栈的实现
数据结构——顺序栈与链式栈的实现-2
|
16小时前
|
存储 C语言
数据结构——顺序栈与链式栈的实现-1
数据结构——顺序栈与链式栈的实现
数据结构——顺序栈与链式栈的实现-1
|
4天前
栈的基本应用
栈的基本应用
11 3
|
4天前
栈与队列理解
栈与队列理解
11 1
|
4天前
|
存储 算法
数据结构与算法 栈与队列
数据结构与算法 栈与队列
10 0
数据结构与算法 栈与队列
|
5天前
|
C++
数据结构(共享栈
数据结构(共享栈
6 0
|
5天前
|
C++
数据结构(顺序栈
数据结构(顺序栈
11 2