数据结构与算法第二套试卷大题

博客介绍了选择排序和插入排序的思路、复杂度及示例,还涉及链表操作,如在双向链表指定位置插入节点;讲解了孩子兄弟表示法画二叉树、二叉排序树特点,介绍了prim算法构造最小生成树,以及集合交集算法设计等信息技术知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.选择排序,插入排序的思路

1.1选择排序思路:
1.每次在数组中选一个最小的元素与第一个元素进行交换——>2.然后逐步缩小数组,重复第一,二步
1.2举例:
假设有一个无序数组 [5, 2, 8, 3, 1],使用选择排序的思路,首先找到最小的元素 1,与数组的第一个元素 5 交换位置,得到 [1, 2, 8, 3, 5],然后在剩余的部分中找到最小的元素 2,与第二个元素 2 交换位置,得到 [1, 2, 8, 3, 5],以此类推,最终得到有序数组 [1, 2, 3, 5, 8];
时间复杂度:0(n^2),空间复杂度:0(1)

2.1插入排序思路:
1.从第二个元素开始,与前面的元素对比,排序到合适的位置——>2.然后重复遍历后面的元素,重复1,2操作
2.2举例:
假设有一个无序数组 [7, 3, 5, 1, 9],使用插入排序的思路,首先将第二个元素 3 插入到已排序部分 [7] 的正确位置,得到 [3, 7, 5, 1, 9],然后将第三个元素 5 插入到已排序部分 [3, 7] 的正确位置,得到 [3, 5, 7, 1, 9],以此类推,最终得到有序数组 [1, 3, 5, 7, 9]
插入排序最优:0(n),平均为0(n^2),空间与上述类似

2.链表操作:

指针变量p指向双向链表中结点A指针变量q指向被插入结点B,要求给出在结点A的后面插入结点B的操作序列(设双向链表
中结点的两个指针域分别为llink和rlink)。
答案:

q->left=p;
q-right=p->right;
p->right->left=q;
p->right=q;

3.孩子兄弟表示法画二叉树

设一棵树T中边的集合为{(A,B),(A,C),(A,D),(B,E),(C,F),(C,G)},要求用孩子兄弟表示法(二叉链表)表示出该树的存储结构并将该树转化成对应的二叉树
方法:抓住左孩子右兄弟即可
在这里插入图片描述

4.二叉排序树

核心: 左边小,根节点第二,右子树最大即可

5.prim算法构造最小生成树

根贪心类似,1.从第一个顶点搜索权值最小的第二节点,绘制路线后,2.从第二各节点再往后搜**(需要判断之前的节点是否有较小的相邻路径**,如果有,就走之前节点的,其次是需要判断是否构成环
请添加图片描述
克鲁斯卡尔算法的话,他是先把边全部排序好,按权值从小到大进行绘制,如果构成环就跳过

6.集合的表示问题

设有两个集合A和集合B,要求设计生成集合C=A∩B的算法,其中集合A、B和C用链式存储结构表示。

//1.节点结构
typedef struct Node{
   int data;
   struct Node* next;
}Node; //后续表示节点直接Node* node即可

//2.链表结构
typedef struct LinkedList{
   Node* head; //节点
}LinkedList; //LinkedList* list表示链表

//3.初始化链表
void initLinkedList(LinkedList* list){
  list->head=NULL;
}

//4.向链表中插入元素
void insert(LinkedList* list,int data){
  //1.创建节点newNode并赋值
  Node*new_node=(Node*)malloc(sizeof(Node));
  new_node->data=data;
  new_node->next=NULL;
  //2.插入
  if(list->head==NULL){
    list->head=new_Node;
  }else{
    //2.2得到头节点
    Node* current=list->head;
    //2.3遍历到尾部
    while(current->next){
      current=current->next;
    }
    //2.3将新的节点插入链表尾部
    current->next=new_Node;
 }

}

// 生成集合C = A ∩ B
LinkedList inersect(LinkedList* list_a,LinkedList* list_b){
   LinkedList* result;
   //1.初始化链表
   initLinkedList(result);
   //2.遍历
   Node* current_a=list_a->head; //先得到链表a的头节点
   while(current_a!=NULL){
     Node* current_b=list_b->head; //链表b的头节点
     while(current_b!=NULL){
       if(current_a->data==current_b->data){
           //满足条件:两链表出现节点相同时,插入c
           insert(result,current_a->data);
           break;  
       }
       //没有找到与a链表相同的节点,继续遍历
       current_b=curent_b->next;
     }
     //遍历a链表
     current_a=current_a->next;
   }
   return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fairy要carry

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

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

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

打赏作者

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

抵扣说明:

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

余额充值