c++数据结构实验链表排序
C语言链表实现冒泡法排序
C语⾔链表实现冒泡法排序功能是:从键盘输⼊字符以空格隔开当输⼊q或者Q时按回车表⽰输⼊结束先放出main函数int main(){MyNode *myNode = (MyNode *)malloc(sizeof(MyNode));if (NULL == myNode) {return 0;}getNum(myNode);sortList(myNode);printStr(myNode);freeStr(myNode);return 0;}然后就结构体#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct mynode{long value;struct mynode *next;}MyNode;最后是⼏个⽅法void getNum(MyNode *myNode){char s[20];printf("please input num and end with q/Q\n");scanf("%s", s);while ((strcmp(s, "q") != 0) && (strcmp(s , "Q") != 0)) {MyNode *temp = (MyNode *)malloc(sizeof(MyNode));if (NULL == temp) {return;}temp->value = strtol(s , 0, 0);temp->next = NULL;myNode->next = temp;myNode = myNode->next;scanf("%s", s);}}void printStr(MyNode *node){if (node == NULL) {return;}MyNode *temp = node;while (temp->next != NULL) {printf("%ld ", temp->next->value);temp = temp->next;}}void sortList(MyNode *node){if (NULL == node) {return;}MyNode *startP = node->next;MyNode *nextP = node->next;while (startP->next != NULL) {nextP = startP->next;while (nextP->next != NULL) {if (startP->next->value > nextP->next->value) { long temp = startP->next->value;startP->next->value = nextP->next->value; nextP->next->value = temp;}nextP = nextP->next;}startP = startP->next;}}void freeStr(MyNode *node){if (NULL == node) {return;}MyNode *old = NULL;while (node != NULL) {printf("d\n");old = node;node = node->next;free(old);}}。
北京邮电大学 数据结构 实验一 带头结点的单链表构造
数据结构实验报告实验名称:实验1——单链表的构造学生姓名:XXXXNB班级:XXXX班内序号:学号:XXXX日期:XXXXX1.实验要求根据线性表的抽象数据类型的定义,完成带头结点的单链表的基本功能。
单链表的基本功能:1、构造:使用头插法、尾插法两种方法2、插入:要求建立的链表按照关键字从小到大有序3、删除4、查找5、获取链表长度6、销毁7、其他:可自行定义编写测试main()函数测试线性表的正确性。
2.程序分编程完成单链表的一般性功能如单链表的构造:使用头插法、尾插法两种方法插入:要求建立的链表按照关键字从小到大有序,删除,查找,获取链表长度,销毁用《数据结构》中的相关思想结合C++语言基本知识编写一个单链表结构。
本程序为使用方便,几乎不用特殊的命令,只需按提示输入即可,适合更多的用户使用。
2.1 存储结构单链表的存储结构:2.2 关键算法分析1.头插法自然语言描述:a.在堆中建立新结点b.将a[i]写入到新结点的数据域c.修改新结点的指针域d.修改头结点的指针域,将新结点加入链表中//在构建之初为了链表的美观性构造,进行了排序代码描述://头插法构造函数template<class T>LinkList<T>::LinkList(T a[], int n){for (int i = n - 1; i >= 1; i--)//冒泡排序,对数组进行从小到大排序{for (int j = 0; j < i; j++){if (a[j]>a[j + 1]){T t = a[j + 1];a[j + 1] = a[j];a[j] = t;}}}front = new Node < T >;//为头指针申请堆空间front->next = NULL;//构造空单链表for (int i = n - 1; i >= 0; i--){Node<T>*s = new Node < T >;//建立新结点s->data = a[i];//将a[i]写入新结点的数据域s->next = front->next;//修改新结点的指针域front->next = s;//修改头结点的指针域,将新结点加入到链表中}}2.尾插法自然语言描述:a.在堆中建立新结点b.将a[i]写入到新结点的数据域c.将新结点加入到链表中d.修改修改尾指针代码描述://尾插法构造函数template<class T>LinkList<T>::LinkList(T a[], int n){front = new Node < T > ;Node<T>*r = front;//命名一个新变量进行转换for (int i = 0; i < n; i++){Node<T>*s = new Node < T > ;s->data = a[i];r->next = s;r = s;}r->next = NULL;}时间复杂度:O(n)3.析构函数自然语言描述:a.新建立一个指针,指向头结点b.移动a中建立的指针c.逐个释放指针代码描述:template<class T>LinkList<T>::~LinkList()//析构函数,销毁链表{Node<T> * p = front;while(p){front = p;p = p->next;delete front;}}4.按位查找函数自然语言描述: a.初始化工作指针p和计数器j,p指向第一个结点,j=1b.循环以下操作,直到p为空或者j等于1b1:p指向下一个结点b2:j加1c.若p为空,说明第i个元素不存在,抛出异常d.否则,说明p指向的元素就是所查找的元素,返回元素地址代码描述:template<class T>Node<T>* LinkList<T>::Get(int i)//按位查找{Node<T> * p = front;int j=0;while(p){if(j<i){p = p->next;j++;}else break;}if(!p) throw"查找位置非法";else return p;}时间复杂度:O(n)5.按值查找函数自然语言描述:a.初始化工作指针p和计数器j,p指向第一个结点,j=1b.循环以下操作,找到这个元素或者p指向最后一个结点b1.判断p指向的结点是不是要查找的值,如果是,返回j;b2.否则p指向下一个结点,并且j的值加一c.如果找到最后一个结点还没有找到要查找的元素,返回查找失败信息代码描述:template<class T>int LinkList<T>::Locate(T x)//按值查找{Node<T> * p = front->next;int j = 1;while(p){if(p->data == x) return j;else{p = p->next;j++;}}return -1;}时间复杂度:O(n)6.插入函数自然语言描述:a.在堆中建立新结点b.将要插入的结点的数据写入到新结点的数据域c.修改新结点的指针域d.修改前一个指针的指针域,使其指向新插入的结点的位置代码描述:template<class T>void LinkList<T>::Insert(int i,T x)//插入函数{Node<T> * p = Get(i-1);if(p){Node<T> * s = new Node<T>;s->data = x;s->next = p->next;p->next = s;}else throw"插入位置非法";}时间复杂度:O(n)7.按位删除函数自然语言描述:a.从第一个结点开始,查找要删除的位数i前一个位置i-1的结点b.设q指向第i个元素c.将q元素从链表中删除d.保存q元素的数据e.释放q元素代码描述:template<class T>T LinkList<T>::Delete(int i)//删除函数{Node<T> *p = Get(i-1);Node<T> *q = p->next;T x=q->data;p->next = q->next;delete q;return x;}8.遍历打印函数自然语言描述: a.判断该链表是否为空链表,如果是,报错b.如果不是空链表,新建立一个temp指针c.将temp指针指向头结点d.打印temp指针的data域e.逐个往后移动temp指针,直到temp指针的指向的指针的next域为空代码描述:template<class T>void LinkList<T>::PrintList()//打印链表{Node<T> * p = front->next;while(p){cout<<p->data<<' ';p = p->next;}cout<<endl;}9.获取链表长度函数自然语言描述:a.判断该链表是否为空链表,如果是,输出长度0b.如果不是空链表,新建立一个temp指针,初始化整形数n为0c.将temp指针指向头结点d.判断temp指针指向的结点的next域是否为空,如果不是,n加一,否则return ne.使temp指针逐个后移,重复d操作,直到temp指针指向的结点的next 域为0,返回n代码描述:template<class T>int LinkList<T>::GetLength()//分析链表长度{Node<T> * p = front;int i=0;while(p){p = p->next;i++;}return i-1;}2.3 其他异常处理采用try catch 函数处理异常如在插入时的异常处理:template<class T>void LinkList<T>::Insert(int i, T x){Node<T>*p = front;if (i != 1) p = Get(i - 1);try{if (p){Node<T>*s = new Node < T > ;s->data = x;s->next = p->next;p->next = s;}else throw i;}catch (int i){cout << "插入到位置 " << i << " 处" << "为错误位置"<<endl;}}3. 程序运行结果主函数流程图:测试截图:初始化链表,菜单创建执行功能:4. 总结.调试时出现了一些问题如:异常抛出的处理,书中并未很好的提及异常处理,通过查阅资料,选择用try catch 函数对解决。
排序的实验报告范文
排序的实验报告范文数据结构实验报告实验名称:实验四排序学生姓名:班级:班内序号:学号:日期:2022年12月21日实验要求题目2使用链表实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、冒泡排序3、快速排序4、简单选择排序5、其他要求:1、测试数据分成三类:正序、逆序、随机数据。
2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)。
4、对2和3的结果进行分析,验证上述各种算法的时间复杂度。
编写测试main()函数测试线性表的正确性。
2、程序分析2.1存储结构说明:本程序排序序列的存储由链表来完成。
其存储结构如下图所示。
(1)单链表存储结构:结点地址:1000HA[2]结点地址:1000H1080H……头指针地址:1020HA[0]头指针地址:1020H10C0H……地址:1080HA[3]地址:1080HNULL……地址:10C0HA[1]地址:10C0H1000H……(2)结点结构tructNode{intdata;Node某ne某t;};示意图:intdataNode某ne某tintdataNode某ne某t2.2关键算法分析一:关键算法(一)直接插入排序voidLinkSort::InertSort()直接插入排序是插入排序中最简单的排序方法,其基本思想是:依次将待排序序列中的每一个记录插入到一个已排好的序列中,直到全部记录都排好序。
(1)算法自然语言1.将整个待排序的记录序列划分成有序区和无序区,初始时有序区为待排序记录序列中的第一个记录,无序区包括所有剩余待排序的记录;2.将无须去的第一个记录插入到有序区的合适位置中,从而使无序区减少一个记录,有序区增加一个记录;3.重复执行2,直到无序区中没有记录为止。
(2)源代码voidLinkSort::InertSort()//从第二个元素开始,寻找前面那个比它大的{Node某P=front->ne某t;//要插入的节点的前驱while(P->ne某t){Node某S=front;//用来比较的节点的前驱while(1){if(P->ne某t->data<S->ne某t->data)//P的后继比S的后继小则插入{inert(P,S);break;}S=S->ne某t;if(S==P)//若一趟比较结束,且不需要插入{P=P->ne某t;break;}}}}(3)时间和空间复杂度最好情况下,待排序序列为正序,时间复杂度为O(n)。
数据结构C语言版 实验报告
数据结构C语言版实验报告一、实验目的本次实验旨在通过使用 C 语言实现常见的数据结构,加深对数据结构基本概念、原理和操作的理解,提高编程能力和解决实际问题的能力。
二、实验环境操作系统:Windows 10编程环境:Visual Studio 2019编程语言:C 语言三、实验内容1、线性表顺序表的实现与操作链表的实现与操作2、栈和队列栈的实现与应用(表达式求值)队列的实现与应用(模拟排队)3、树和二叉树二叉树的遍历(前序、中序、后序)二叉搜索树的实现与操作4、图图的存储结构(邻接矩阵、邻接表)图的遍历(深度优先搜索、广度优先搜索)四、实验步骤及结果1、线性表顺序表的实现与操作定义顺序表的数据结构,包括数组和表的长度。
实现顺序表的初始化、插入、删除、查找等操作。
测试顺序表的各种操作,输出操作结果。
```cinclude <stdioh>include <stdlibh>define MAX_SIZE 100typedef struct {int dataMAX_SIZE;int length;} SeqList;//初始化顺序表void initList(SeqList L) {L>length = 0;}//插入元素到顺序表int insertList(SeqList L, int pos, int element) {if (L>length >= MAX_SIZE || pos < 0 || pos > L>length) {return 0;}for (int i = L>length 1; i >= pos; i) {L>datai + 1 = L>datai;}L>datapos = element;L>length++;return 1;}//删除顺序表中的元素int deleteList(SeqList L, int pos) {if (pos < 0 || pos >= L>length) {return 0;}for (int i = pos; i < L>length 1; i++){L>datai = L>datai + 1;}L>length;return 1;}//查找顺序表中的元素int searchList(SeqList L, int element) {for (int i = 0; i < Llength; i++){if (Ldatai == element) {return i;}}return -1;}int main(){SeqList L;initList(&L);insertList(&L, 0, 10);insertList(&L, 1, 20);insertList(&L, 2, 30);printf("顺序表元素: ");for (int i = 0; i < Llength; i++){printf("%d ", Ldatai);}printf("\n");int pos = searchList(L, 20);if (pos!=-1) {printf("元素 20 在顺序表中的位置: %d\n", pos);} else {printf("顺序表中未找到元素 20\n");}deleteList(&L, 1);printf("删除元素后的顺序表元素: ");for (int i = 0; i < Llength; i++){printf("%d ", Ldatai);}printf("\n");return 0;}```实验结果:成功实现顺序表的初始化、插入、删除、查找等操作,输出结果符合预期。
数据结构排序实验报告
数据结构排序实验报告数据结构排序实验报告引言:数据结构是计算机科学中的重要概念之一,它涉及到数据的组织、存储和操作方式。
排序是数据结构中的基本操作之一,它可以将一组无序的数据按照特定的规则进行排列,从而方便后续的查找和处理。
本实验旨在通过对不同排序算法的实验比较,探讨它们的性能差异和适用场景。
一、实验目的本实验的主要目的是通过实际操作,深入理解不同排序算法的原理和实现方式,并通过对比它们的性能差异,选取合适的排序算法用于不同场景中。
二、实验环境和工具实验环境:Windows 10 操作系统开发工具:Visual Studio 2019编程语言:C++三、实验过程1. 实验准备在开始实验之前,我们需要先准备一组待排序的数据。
为了保证实验的公正性,我们选择了一组包含10000个随机整数的数据集。
这些数据将被用于对比各种排序算法的性能。
2. 实验步骤我们选择了常见的五种排序算法进行实验比较,分别是冒泡排序、选择排序、插入排序、快速排序和归并排序。
- 冒泡排序:该算法通过不断比较相邻元素的大小,将较大的元素逐渐“冒泡”到数组的末尾。
实现时,我们使用了双重循环来遍历整个数组,并通过交换元素的方式进行排序。
- 选择排序:该算法通过不断选择数组中的最小元素,并将其放置在已排序部分的末尾。
实现时,我们使用了双重循环来遍历整个数组,并通过交换元素的方式进行排序。
- 插入排序:该算法将数组分为已排序和未排序两部分,然后逐个将未排序部分的元素插入到已排序部分的合适位置。
实现时,我们使用了循环和条件判断来找到插入位置,并通过移动元素的方式进行排序。
- 快速排序:该算法通过选取一个基准元素,将数组分为两个子数组,并对子数组进行递归排序。
实现时,我们使用了递归和分治的思想,将数组不断划分为更小的子数组进行排序。
- 归并排序:该算法通过将数组递归地划分为更小的子数组,并将子数组进行合并排序。
实现时,我们使用了递归和分治的思想,将数组不断划分为更小的子数组进行排序,然后再将子数组合并起来。
数据结构实验报告-排序
本章共8道实验题目。
一、直接插入排序1. 定义顺序表的存储结构2. 初始化顺序表为空表3. 输入10个元素创建含有10个元素的顺序表4. 输出顺序表5. 对顺序表进行直接插入排序(InsertSort)6. 输出排序后的顺序表例如:11 938 669 507 117 261 708 343 300 60211 938 669 507 117 261 708 343 300 60211 117 261 300 343 507 602 669 708 938程序:#include <iostream>#include <algorithm>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define MAXSIZE 100typedef int KeyType;typedef char InfoType[256];typedef struct{KeyType key;InfoType otherinfo;}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}SqList;//此处定义直接插入排序函数int a[20];int main(){int InsertSort;for (int i = 0; i < 10; ++i){cin >> a[i];cout << a[i] << " ";}cout << endl;sort(a, a+10);for (int i = 0; i < 10; ++i)cout << a[i] << " ";return 0;}二、折半插入排序1. 定义顺序表的存储结构2. 初始化顺序表为空表3. 输入10个元素创建含有10个元素的顺序表4. 输出顺序表5. 对顺序表进行折半插入排序(BInsertSort)6. 输出排序后的顺序表例如:11 938 669 507 117 261 708 343 300 60211 938 669 507 117 261 708 343 300 60211 117 261 300 343 507 602 669 708 938程序:#include <iostream>#include <algorithm>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define MAXSIZE 100typedef int KeyType;typedef char InfoType[256];typedef struct{KeyType key;InfoType otherinfo;}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}SqList;//此处定义折半插入排序函数int a[20];int main(){int BInsertSort ;for (int i = 0; i < 10; ++i){cin >> a[i];cout << a[i] << " ";}cout << endl;sort(a, a+10);for (int i = 0; i < 10; ++i)cout << a[i] << " ";return 0;}三、希尔排序1. 定义顺序表的存储结构2. 初始化顺序表为空表3. 输入10个元素创建含有10个元素的顺序表4. 输出顺序表5. 对顺序表进行希尔排序(ShellSort)6. 输出排序后的顺序表例如:11 938 669 507 117 261 708 343 300 602 11 938 669 507 117 261 708 343 300 602 11 117 261 300 343 507 602 669 708 938 程序:#include <iostream>#include <algorithm>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define MAXSIZE 100typedef int KeyType;typedef char InfoType[256];typedef struct{KeyType key;InfoType otherinfo;}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}SqList;int a[20];int main(){int ShellSort;for (int i = 0; i < 10; ++i){cin >> a[i];cout << a[i] << " ";}cout << endl;sort(a, a+10);for (int i = 0; i < 10; ++i)cout << a[i] << " ";return 0;}四、冒泡排序1.定义顺序表的存储结构2.初始化顺序表为空表3.输入10个元素创建含有10个元素的顺序表4.输出顺序表5.对顺序表进行冒泡排序(BubbleSort)6.输出排序后的顺序表例如:11 938 669 507 117 261 708 343 300 60211 938 669 507 117 261 708 343 300 60211 117 261 300 343 507 602 669 708 938程序:#include <iostream>#include <algorithm>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define MAXSIZE 100typedef int KeyType;typedef char InfoType[256];typedef struct{KeyType key;InfoType otherinfo;}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}SqList;int a[20];int main(){int BubbleSort;for (int i = 0; i < 10; ++i){cin >> a[i];cout << a[i] << " ";}cout << endl;sort(a, a+10);for (int i = 0; i < 10; ++i)cout << a[i] << " ";return 0;}五、快速排序1.定义顺序表的存储结构2.初始化顺序表为空表3.输入10个元素创建含有10个元素的顺序表4.输出顺序表5.对顺序表进行快速排序(QuickSort)6.输出排序后的顺序表例如:11 938 669 507 117 261 708 343 300 60211 938 669 507 117 261 708 343 300 60211 117 261 300 343 507 602 669 708 938程序:#include <iostream>#include <algorithm>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define MAXSIZE 100typedef int KeyType;typedef char InfoType[256];typedef struct{KeyType key;InfoType otherinfo;}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}SqList;int a[20];int main(){int QuickSort;for (int i = 0; i < 10; ++i){cin >> a[i];cout << a[i] << " ";}cout << endl;sort (a, a+10);for (int i = 0; i < 10; ++i)cout << a[i] << " ";return 0;}六、简单选择排序1.定义顺序表的存储结构2.初始化顺序表为空表3.输入10个元素创建含有10个元素的顺序表4.输出顺序表5.对顺序表进行简单选择排序(SelectSort)6.输出排序后的顺序表例如:11 938 669 507 117 261 708 343 300 60211 938 669 507 117 261 708 343 300 602 11 117 261 300 343 507 602 669 708 938 程序:#include <iostream>#include <algorithm>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define MAXSIZE 100typedef int KeyType;typedef char InfoType[256];typedef struct{KeyType key;InfoType otherinfo;}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}SqList;int a[20];int main(){int SelectSort;for (int i = 0; i < 10; ++i){cin >> a[i];cout << a[i] << " ";}cout << endl;sort(a, a+10);for (int i = 0; i < 10; ++i)cout << a[i] << " ";return 0;}七、堆排序1.定义顺序表的存储结构2.初始化顺序表为空表3.输入10个元素创建含有10个元素的顺序表4.输出顺序表5.对顺序表进行堆排序(HeapSort)6.输出排序后的顺序表例如:11 938 669 507 117 261 708 343 300 60211 938 669 507 117 261 708 343 300 60211 117 261 300 343 507 602 669 708 938程序:#include <iostream>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define MAXSIZE 100typedef int KeyType;typedef char InfoType[256];typedef struct{KeyType key;InfoType otherinfo;}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}SqList;Status InitList(SqList &L){L.length=0;return 0;}Status CreateList(SqList &L,int n){if(!L.r||n<1||n>MAXSIZE) return ERROR;//cout<<"\n请输入"<<n<<"个元素(用空格隔开):";for(int i=1;i<=n;i++)cin>>L.r[i].key;L.length=n;return OK;}void ListTraverse(SqList L){//cout<<"L=(";for(int i=1;i<=L.length;i++)cout<<L.r[i].key<<' ';//if(L.length) cout<<'\b';//cout<<")";cout<<endl;}void HeapSort(SqList &L){int value = 0;for(int i = 0;i<L.length;i++)for(int j = 0;j<L.length-i;j++){if(L.r[j].key>L.r[j+1].key){value = L.r[j].key;L.r[j].key= L.r[j+1].key;L.r[j+1].key = value;}}int main(){SqList L;InitList(L);CreateList(L,10);ListTraverse(L);HeapSort(L);ListTraverse(L);return 0;}八、归并排序1.定义顺序表的存储结构2.初始化顺序表为空表3.输入10个元素创建含有10个元素的顺序表4.输出顺序表5.对顺序表进行二路归并排序(MergeSort)6.输出排序后的顺序表例如:11 938 669 507 117 261 708 343 300 60211 938 669 507 117 261 708 343 300 60211 117 261 300 343 507 602 669 708 938程序:#include <iostream>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;#define MAXSIZE 100typedef int KeyType;typedef char InfoType[256];typedef structKeyType key;InfoType otherinfo;}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}SqList;Status InitList(SqList &L){L.length=0;return 0;}Status CreateList(SqList &L,int n){if(!L.r||n<1||n>MAXSIZE) return ERROR;//cout<<"\n请输入"<<n<<"个元素(用空格隔开):";for(int i=1;i<=n;i++)cin>>L.r[i].key;L.length=n;return OK;}void ListTraverse(SqList L){//cout<<"L=(";for(int i=1;i<=L.length;i++)cout<<L.r[i].key<<' ';//if(L.length) cout<<'\b';//cout<<")";cout<<endl;}void MSort(){}void Merge(){}void MergeSort(SqList &L){int value = 0;for(int i = 0;i<L.length;i++)for(int j = 0;j<L.length-i;j++){if(L.r[j].key>L.r[j+1].key){value = L.r[j].key;L.r[j].key= L.r[j+1].key;L.r[j+1].key = value;}}}int main(){SqList L;InitList(L);CreateList(L,10);ListTraverse(L);MergeSort(L);ListTraverse(L);return 0;}。
c语言链表排序算法
c语言链表排序算法在C语言中,链表的排序可以使用多种算法,如插入排序、归并排序、快速排序等。
以下是一个简单的插入排序算法的示例,用于对链表进行排序:C:#include<stdio.h>#include<stdlib.h>struct Node {int data;struct Node* next;};void insert(struct Node** head, int data) {struct Node* newNode= (struct Node*)malloc(sizeof(struct Node));newNode->data = data;newNode->next = NULL;if (*head == NULL) {*head = newNode;return;}struct Node* current = *head;while (current->next != NULL) {current = current->next;}current->next = newNode;}void sortList(struct Node** head) { struct Node* current = *head;while (current != NULL) {struct Node* next = current->next; while (next != NULL) {if (current->data > next->data) { int temp = current->data;current->data = next->data;next->data = temp;}next = next->next;}current = current->next;}}void printList(struct Node* head) { while (head != NULL) {printf("%d ", head->data);head = head->next;}}int main() {struct Node* head = NULL;insert(&head, 5);insert(&head, 2);insert(&head, 4);insert(&head, 1);insert(&head, 3);printf("Before sorting: ");printList(head);sortList(&head);printf("\nAfter sorting: ");printList(head);return0;}这个程序定义了一个链表节点结构体Node,其中包含一个整型数据data 和一个指向下一个节点的指针next。
数据结构 实验报告
数据结构实验报告一、实验目的数据结构是计算机科学中非常重要的一门课程,通过本次实验,旨在加深对常见数据结构(如链表、栈、队列、树、图等)的理解和应用,提高编程能力和解决实际问题的能力。
二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。
操作系统为 Windows 10。
三、实验内容1、链表的实现与操作创建一个单向链表,并实现插入、删除和遍历节点的功能。
对链表进行排序,如冒泡排序或插入排序。
2、栈和队列的应用用栈实现表达式求值,能够处理加、减、乘、除和括号。
利用队列实现银行排队系统的模拟,包括顾客的到达、服务和离开。
3、二叉树的遍历与操作构建一棵二叉树,并实现前序、中序和后序遍历。
进行二叉树的插入、删除节点操作。
4、图的表示与遍历用邻接矩阵和邻接表两种方式表示图。
实现图的深度优先遍历和广度优先遍历。
四、实验步骤及结果1、链表的实现与操作首先,定义了链表节点的结构体:```cppstruct ListNode {int data;ListNode next;ListNode(int x) : data(x), next(NULL) {}};```插入节点的函数:```cppvoid insertNode(ListNode& head, int val) {ListNode newNode = new ListNode(val);head = newNode;} else {ListNode curr = head;while (curr>next!= NULL) {curr = curr>next;}curr>next = newNode;}}```删除节点的函数:```cppvoid deleteNode(ListNode& head, int val) {if (head == NULL) {return;}ListNode temp = head;head = head>next;delete temp;return;}ListNode curr = head;while (curr>next!= NULL && curr>next>data!= val) {curr = curr>next;}if (curr>next!= NULL) {ListNode temp = curr>next;curr>next = curr>next>next;delete temp;}}```遍历链表的函数:```cppvoid traverseList(ListNode head) {ListNode curr = head;while (curr!= NULL) {std::cout << curr>data <<"";curr = curr>next;}std::cout << std::endl;}```对链表进行冒泡排序的函数:```cppvoid bubbleSortList(ListNode& head) {if (head == NULL || head>next == NULL) {return;}bool swapped;ListNode ptr1;ListNode lptr = NULL;do {swapped = false;ptr1 = head;while (ptr1->next!= lptr) {if (ptr1->data > ptr1->next>data) {int temp = ptr1->data;ptr1->data = ptr1->next>data;ptr1->next>data = temp;swapped = true;}ptr1 = ptr1->next;}lptr = ptr1;} while (swapped);}```测试结果:创建了一个包含 5、3、8、1、4 的链表,经过排序后,输出为 1 3 4 5 8 。
链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)
链表排序(冒泡、选择、插⼊、快排、归并、希尔、堆排序)这篇⽂章分析⼀下链表的各种排序⽅法。
以下排序算法的正确性都可以在LeetCode的这⼀题检测。
本⽂⽤到的链表结构如下(排序算法都是传⼊链表头指针作为参数,返回排序后的头指针)struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}};插⼊排序(算法中是直接交换节点,时间复杂度O(n^2),空间复杂度O(1))class Solution {public:ListNode *insertionSortList(ListNode *head) {// IMPORTANT: Please reset any member data you declared, as// the same Solution instance will be reused for each test case.if(head == NULL || head->next == NULL)return head;ListNode *p = head->next, *pstart = new ListNode(0), *pend = head;pstart->next = head; //为了操作⽅便,添加⼀个头结点while(p != NULL){ListNode *tmp = pstart->next, *pre = pstart;while(tmp != p && p->val >= tmp->val) //找到插⼊位置{tmp = tmp->next; pre = pre->next;}if(tmp == p)pend = p;else{pend->next = p->next;p->next = tmp;pre->next = p;}p = pend->next;}head = pstart->next;delete pstart;return head;}};选择排序(算法中只是交换节点的val值,时间复杂度O(n^2),空间复杂度O(1))class Solution {public:ListNode *selectSortList(ListNode *head) {// IMPORTANT: Please reset any member data you declared, as// the same Solution instance will be reused for each test case.//选择排序if(head == NULL || head->next == NULL)return head;ListNode *pstart = new ListNode(0);pstart->next = head; //为了操作⽅便,添加⼀个头结点ListNode*sortedTail = pstart;//指向已排好序的部分的尾部while(sortedTail->next != NULL){ListNode*minNode = sortedTail->next, *p = sortedTail->next->next;//寻找未排序部分的最⼩节点while(p != NULL){if(p->val < minNode->val)minNode = p;p = p->next;}swap(minNode->val, sortedTail->next->val);sortedTail = sortedTail->next;}head = pstart->next;delete pstart;return head;}};快速排序1(算法只交换节点的val值,平均时间复杂度O(nlogn),不考虑递归栈空间的话空间复杂度是O(1))这⾥的partition我们参考(选取第⼀个元素作为枢纽元的版本,因为链表选择最后⼀元素需要遍历⼀遍),具体可以参考这⾥我们还需要注意的⼀点是数组的partition两个参数分别代表数组的起始位置,两边都是闭区间,这样在排序的主函数中:void quicksort(vector<int>&arr, int low, int high){if(low < high){int middle = mypartition(arr, low, high);quicksort(arr, low, middle-1);quicksort(arr, middle+1, high);}}对左边⼦数组排序时,⼦数组右边界是middle-1,如果链表也按这种两边都是闭区间的话,找到分割后枢纽元middle,找到middle-1还得再次遍历数组,因此链表的partition采⽤前闭后开的区间(这样排序主函数也需要前闭后开区间),这样就可以避免上述问题class Solution {public:ListNode *quickSortList(ListNode *head) {// IMPORTANT: Please reset any member data you declared, as// the same Solution instance will be reused for each test case.//链表快速排序if(head == NULL || head->next == NULL)return head;qsortList(head, NULL);return head;}void qsortList(ListNode*head, ListNode*tail){//链表范围是[low, high)if(head != tail && head->next != tail){ListNode* mid = partitionList(head, tail);qsortList(head, mid);qsortList(mid->next, tail);}}ListNode* partitionList(ListNode*low, ListNode*high){//链表范围是[low, high)int key = low->val;ListNode* loc = low;for(ListNode*i = low->next; i != high; i = i->next)if(i->val < key){loc = loc->next;swap(i->val, loc->val);}swap(loc->val, low->val);return loc;}};快速排序2(算法交换链表节点,平均时间复杂度O(nlogn),不考虑递归栈空间的话空间复杂度是O(1))这⾥的partition,我们选取第⼀个节点作为枢纽元,然后把⼩于枢纽的节点放到⼀个链中,把不⼩于枢纽的及节点放到另⼀个链中,最后把两条链以及枢纽连接成⼀条链。
数据结构(C语言版)实验报告 (内部排序算法比较)
《数据结构与算法》实验报告一、需求分析问题描述:在教科书中,各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。
试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。
基本要求:(l)对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。
(2)待排序表的表长不小于100000;其中的数据要用伪随机数程序产生;至少要用5组不同的输入数据作比较;比较的指标为有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动)。
(3)最后要对结果作简单分析,包括对各组数据得出结果波动大小的解释。
数据测试:二.概要设计1.程序所需的抽象数据类型的定义:typedef int BOOL; //说明BOOL是int的别名typedef struct StudentData { int num; //存放关键字}Data; typedef struct LinkList { int Length; //数组长度Data Record[MAXSIZE]; //用数组存放所有的随机数} LinkList int RandArray[MAXSIZE]; //定义长度为MAXSIZE的随机数组void RandomNum() //随机生成函数void InitLinkList(LinkList* L) //初始化链表BOOL LT(int i, int j,int* CmpNum) //比较i和j 的大小void Display(LinkList* L) //显示输出函数void ShellSort(LinkList* L, int dlta[], int t,int* CmpNum, int* ChgNum) //希尔排序void QuickSort (LinkList* L, int* CmpNum, int* ChgNum) //快速排序void HeapSort (LinkList* L, int* CmpNum, int* ChgNum) //堆排序void BubbleSort(LinkList* L, int* CmpNum, int* ChgNum) //冒泡排序void SelSort(LinkList* L, int* CmpNum, int* ChgNum) //选择排序void Compare(LinkList* L,int* CmpNum, int* ChgNum) //比较所有排序2 .各程序模块之间的层次(调用)关系:二、详细设计typedef int BOOL; //定义标识符关键字BOOL别名为int typedef struct StudentData //记录数据类型{int num; //定义关键字类型}Data; //排序的记录数据类型定义typedef struct LinkList //记录线性表{int Length; //定义表长Data Record[MAXSIZE]; //表长记录最大值}LinkList; //排序的记录线性表类型定义int RandArray[MAXSIZE]; //定义随机数组类型及最大值/******************随机生成函数********************/void RandomNum(){int i; srand((int)time(NULL)); //用伪随机数程序产生伪随机数for(i=0; i小于MAXSIZE; i++) RandArray[i]<=(int)rand(); 返回;}/*****************初始化链表**********************/void InitLinkList(LinkList* L) //初始化链表{int i;memset(L,0,sizeof(LinkList));RandomNum();for(i=0; i小于<MAXSIZE; i++)L->Record[i].num<=RandArray[i]; L->Length<=i;}BOOL LT(int i, int j,int* CmpNum){(*CmpNum)++; 若i<j) 则返回TRUE; 否则返回FALSE;}void Display(LinkList* L){FILE* f; //定义一个文件指针f int i;若打开文件的指令不为空则//通过文件指针f打开文件为条件判断{ //是否应该打开文件输出“can't open file”;exit(0); }for (i=0; i小于L->Length; i++)fprintf(f,"%d\n",L->Record[i].num);通过文件指针f关闭文件;三、调试分析1.调试过程中遇到的问题及经验体会:在本次程序的编写和调试过程中,我曾多次修改代码,并根据调试显示的界面一次次调整代码。
数据结构实验报告(C语言)顺序表__排序
int i,j,n,x,change; n=L->length; change=1; for(i=1;i<=n-1 && change;++i){
change=0; for(j=1;j<=n-i-1;++j)
if(L->r[j] > L->r[j+1]){ x=L->r[j]; L->r[j]=L->r[j+1]; L->r[j+1]=x; change=1;
void QuickSort(SqeList *L,int low,int high){ int mid; if(low<high){ mid=Partition(L,low,high); QuickSort(L,low,mid-1); QuickSort(L,mid+1,high); }
}
//直接选择排序
printf("\n7-直接选择排序结果为:\n"); SelectSort(&l); PrintList(&l); printf("\n"); printf("\n8-二路归并结果为:\n"); MergeSort(&l);
PrintList(&l); printf("\n"); } else printf("请输入大于 0 的值: "); return 0; }
} else{
MR->r[k]=R->r[j]; ++j; } ++k; } while(i<=mid) MR->r[k++]=R->r[i++]; while(j<=high) MR->r[k++]=R->r[j++]; }
冒泡排序链表c语言
冒泡排序链表c语言冒泡排序是一种简单而常用的排序算法,它可以用于对链表进行排序。
在本文中,我们将介绍如何使用C语言实现冒泡排序链表,并解释算法的原理和步骤。
让我们来了解一下冒泡排序的基本原理。
冒泡排序通过多次遍历待排序的元素,比较相邻的两个元素的大小,并根据需要交换它们的位置。
通过这样的比较和交换,最大(或最小)的元素会逐渐“冒泡”到列表的末尾(或开头),从而实现排序。
在链表中实现冒泡排序的思路与数组类似,但需要注意的是,我们无法像数组那样通过下标直接访问链表中的元素。
因此,在链表中进行元素比较和交换时,我们需要修改节点之间的连接关系。
下面是使用C语言实现冒泡排序链表的步骤:1. 遍历链表,确定链表的长度。
这一步是为了确定需要进行多少次排序遍历。
2. 写一个循环,循环次数为链表的长度减1。
每次循环都进行一次完整的遍历和排序。
3. 在每次遍历中,从链表的头部开始,比较相邻节点的值。
如果前一个节点的值大于后一个节点的值,则交换它们的位置。
4. 重复步骤3,直到遍历到链表的倒数第二个节点。
这样可以确保在每次遍历后,链表的最后一个节点都是当前遍历范围内的最大(或最小)值。
5. 重复步骤2和步骤3,直到完成所有的排序遍历。
此时,链表中的元素已经按照从小到大(或从大到小)的顺序排列好了。
以下是冒泡排序链表的C语言代码实现:```c#include <stdio.h>// 定义链表节点的结构体typedef struct Node {int data;struct Node* next;} Node;// 冒泡排序链表的函数void bubbleSortList(Node* head) {if (head == NULL || head->next == NULL) {return;}int len = 0;Node* cur = head;while (cur != NULL) {len++;cur = cur->next;}for (int i = 0; i < len - 1; i++) {cur = head;for (int j = 0; j < len - i - 1; j++) {if (cur->data > cur->next->data) { int temp = cur->data;cur->data = cur->next->data; cur->next->data = temp;}cur = cur->next;}}}// 打印链表的函数void printList(Node* head) {Node* cur = head;while (cur != NULL) {printf("%d ", cur->data);cur = cur->next;}printf("\n");}int main() {// 创建链表Node* head = (Node*)malloc(sizeof(Node)); Node* node1 = (Node*)malloc(sizeof(Node)); Node* node2 = (Node*)malloc(sizeof(Node)); Node* node3 = (Node*)malloc(sizeof(Node)); head->data = 3;node1->data = 2;node2->data = 4;node3->data = 1;head->next = node1;node1->next = node2;node2->next = node3;node3->next = NULL;// 打印排序前的链表printf("排序前的链表:");printList(head);// 对链表进行冒泡排序bubbleSortList(head);// 打印排序后的链表printf("排序后的链表:");printList(head);return 0;}```在上面的代码中,我们首先定义了一个链表节点的结构体,其中包含一个整型数据成员和一个指向下一个节点的指针成员。
C语言链表的排序
C语言链表的排序/某==========================功能:选择排序(由小到大)返回:指向链表表头的指针==========================某//某选择排序的基本思想就是反复从还未排好序的那些节点中,选出键值(就是用它排序的字段,我们取学号num为键值)最小的节点,依次重新组合成一个链表。
head存储的是第一个节点的地址,head->ne某t存储的是第二个节点的地址;任意一个节点p的地址,只能通过它前一个节点的ne某t来求得。
单向链表的选择排序图示:---->[1]---->[3]---->[2]...---->[n]---->[NULL](原链表)head1->ne某t3->ne某t2->ne某tn->ne某t---->[NULL](空链表)firttail---->[1]---->[2]---->[3]...---->[n]---->[NULL](排序后链表)firt1->ne某t2->ne某t3->ne某ttail->ne某t图10:有N个节点的链表选择排序1、先在原链表中找最小的,找到一个后就把它放到另一个空的链表中;2、空链表中安放第一个进来的节点,产生一个有序链表,并且让它在原链表中分离出来(此时要注意原链表中出来的是第一个节点还是中间其它节点);3、继续在原链表中找下一个最小的,找到后把它放入有序链表的尾指针的ne某t,然后它变成其尾指针;某/tructtudent某SelectSort(tructtudent某head){tructtudent某firt;/某排列后有序链的表头指针某/tructtudent 某tail;/某排列后有序链的表尾指针某/tructtudent某p_min;/某保留键值更小的节点的前驱节点的指针某/tructtudent某min;/某存储最小节点某/tructtudent某p;/某当前比较的节点某/firt=NULL;while(head!=NULL)/某在链表中找键值最小的节点。
数据结构c++顺序表、单链表的基本操作,查找、排序代码
} return 0; }
实验三 查找
实验名称: 实验3 查找 实验目的:掌握顺序表和有序表的查找方法及算法实现;掌握二叉排序 树和哈希表的构造和查找方法。通过上机操作,理解如何科学地组织信 息存储,并选择高效的查找算法。 实验内容:(2选1)内容1: 基本查找算法;内容2: 哈希表设计。 实验要求:1)在C++系统中编程实现;2)选择合适的数据结构实现查 找算法;3)写出算法设计的基本原理或画出流程图;4)算法实现代码 简洁明了;关键语句要有注释;5)给出调试和测试结果;6)完成实验 报告。 实验步骤: (1)算法设计 a.构造哈希函数的方法很多,常用的有(1)直接定址法(2)数字分析法;(3) 平方取中法;(4)折叠法;( 5)除留余数法;(6)随机数法;本实验采用的是除 留余数法:取关键字被某个不大于哈希表表长m的数p除后所得余数为哈 希地址 (2)算法实现 hash hashlist[n]; void listname(){ char *f; int s0,r,i; NameList[0].py="baojie"; NameList[1].py="chengቤተ መጻሕፍቲ ባይዱoyang"; ……………………………… NameList[29].py="wurenke"; for(i=0;i<q;i++){s0=0;f=NameList[i].py; for(r=0;*(f+r)!='\0';r++) s0+=*(f+r);NameList[i].k=s0; }} void creathash(){int i;
v[k-1]=v[k]; nn=nn-1; return ; } int main() {sq_LList<double>s1(100); cout<<"第一次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); s1.ins_sq_LList(0,1.5); s1.ins_sq_LList(1,2.5); s1.ins_sq_LList(4,3.5); cout<<"第二次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); s1.del_sq_LList(0); s1.del_sq_LList(2); cout<<"第三次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); return 0; } 运行及结果:
数据结构课程设计 实验报告 心得体会 链表 C语言
数据结构课程设计设计题目: 两个链表的交叉合并专业班级:08软件工程3班姓名:xxxxxx学号: 080107031123设计时间:2010/9/25指导教师:杨薇薇一、设计题目实现两个链表的合并设计目的1.掌握线性链表的建立。
2.掌握线性链表的基本操作。
设计内容和要求1. 建立两个链表A和B,链表元素个数分别为m和n个。
2. 假设元素分别为(x1,x2,…xm),和(y1,y2, …yn)。
把它们合并成一个线形表C,使得:当m>=n时,C=x1,y1,x2,y2,...xn,yn, (x)当n>m时,C=y1,x1,y2,x2,…ym,xm,…,yn输出线性表C。
3. 用直接插入排序法对C进行升序排序,生成链表D,并输出链表D。
4. 能删除指定单链表中指定位子和指定值的元素。
二、运行环境(软、硬件环境)软件环境: VC++6.0编程软件,运行平台:Win32硬件:普通个人pc机、算法设计的思想三、算法的流程图四、算法设计分析这个两个链表的交叉合并算法主要运用到的是链表的基本操作,定义节点,将链表的创建、计算链表的长度、链表A,B的交叉组合、链表内容升序排列、删除链表指定位置元素、删除指定的元素等算法写成了独立函数,通过主函数调用。
这样就大大精简了主函数的操作。
但主函数中很大篇幅用到了if、else语句,用以指定链表指定结点和指定元素的删除操作,这样就使得本来很精简变得繁琐,降低了程序的质量。
所以其有优点和缺点,但需要不断的改进,不断优化该程序。
五、源代码程序源代码:#include<stdio.h>#include<stdlib.h>typedef struct node //节点定义{int data;struct node *next;} node,*linklist;linklist creat(linklist head) //该函数用来创建链表{node *r,*s;int a;r = (linklist)malloc(sizeof(node));head = r;scanf("%d",&a);while(a != 0){s =(node*)malloc(sizeof(node));s->data=a;r->next=s;r=s;printf("please input a data:");scanf("%d",&a);}r->next=NULL;return head;}linklist length(linklist l) // 返回L中数据元素个数{int i=0;linklist p=l->next; // p指向第一个结点while(p){i++;p=p->next;}return i;}linklist mergel(linklist A,linklist B) //用于实现链表A,B的交叉组合 {int m,n;node *p,*q,*s,*t;linklist C;p=A->next;q=B->next;m=length(A);n=length(B);C=A;if(m<n){p=B->next;q=A->next;C=B;}while(p&&q){s=p->next;p->next=q;if(s){t=q->next;q->next=s;}p=s;q=t;}return C;}linklist sort(linklist L) //链表内容升序排列{linklist p,q,min;int temp;p=L;while( p=p->next ){q=min=p;while(q=q->next){if( q->data<min->data )min = q;}if( min!=p ){temp = p->data;p->data = min->data;min->data=temp;}}return L;}linklist Delete(linklist l,int index) //删除链表指定位置元素{ linklist p,t;int cx=1; //用于计数p=l;if(index<length(l)){while(p&&(cx<index)){t=p;p=p->next;cx++;}t->next=p->next;}elseprintf("input indext error");return l;}linklist Delete_element(linklist l,int data) //删除指定的元素{ linklist p;p=l;if(p->next){while(p->next->data!=data){p=p->next;}p->next=p->next->next;}elseprintf("don't faind the element");return l;}linklist display(linklist l) //打印{ linklist p;printf("new linklist :\n");p = l->next;while(p){printf("%d\n",p->data);p= p->next;}return l;}main(){linklist p,q,A,B,C,D;int indexs;int datas;char name;int cmd;printf("Creat linklist A:\n"); //创建A链表,并打印printf("please input a data:");A = creat(A);printf("Creat linklist B:\n"); //创建B链表,并打印printf("please input a data:");B = creat(B);C = mergel(A,B); //生成C链表,并打印 printf("linklist C\n");p = C->next;while(p){printf("%d\n",p->data);p=p->next;}D=C; //对C进行排序生成D sort(D);printf("linklist D:\n");q = D->next;while(q){printf("%d\n",q->data);q = q->next;}printf("\nplease input 0 or 1 \n");//用1和0判断是按位置删除还是直接删除元素scanf("%d",&cmd);if(cmd==0) //位置删除{printf("please input linklist name\n ");fflush(stdin);scanf("%c",&name);printf("\nplease input index \n");scanf("%d",&indexs);fflush(stdin);if(name=='A'){Delete(A,indexs);display(A);}else if(name=='B'){Delete(B,indexs);display(B);}else if(name=='C'){Delete(C,indexs);display(C);}else if(name=='D'){Delete(D,indexs);display(D);}elseprintf("nameError");}else if(cmd==1) //元素删除{fflush(stdin); //清除缓冲printf("please input linklist name\n ");//fflush(stdin);scanf("%c",&name);printf("\nplease input datas \n");scanf("%d",&datas);if(name=='A'){Delete_element(A,datas);display(A);}else if(name=='B'){Delete_element(B,datas);display(B);}else if(name=='C'){Delete_element(C,datas);display(C);}else if(name=='D'){Delete_element(D,datas);display(D);}elseprintf("name2error");}elseprintf("cmdError");printf("\nOver\n"); getchar();return 0;}六、运行结果分析截图:结果分析:大体来说,该程序都实现了课程设计的算法要求及功能,但还是有很多问题,由于时间问题该算法做得比较粗糙,还不能很好的处理问题,例如,如果想在一次操作完成后还像再次操作,但此时已经结束算法了,需要重新运行程序再次输入操作才能达到要求,这样很繁琐。
数据结构排序实验报告
引言概述:数据结构排序实验是计算机科学与技术专业中一项重要的实践课程。
通过实验,可以深入理解和掌握不同排序算法的原理、特点和性能表现。
本文将针对数据结构排序实验进行详细的阐述和总结,包括实验目的、实验内容、实验结果分析和总结。
一、实验目的1. 加深对数据结构排序算法的理解:通过实验,掌握不同排序算法的工作原理和实现方式。
2. 分析和比较不同排序算法的性能:对比不同排序算法在不同数据规模下的时间复杂度和空间复杂度,理解它们的优劣势。
3. 提高编程和算法设计能力:通过实验的编写,提升对排序算法的实现能力和代码质量。
二、实验内容1. 选择排序算法:选择排序是一种简单直观的排序算法,将序列分为有序和无序两部分,每次从无序部分选择最小(最大)元素,放到有序部分的末尾(开头)。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析2. 插入排序算法:插入排序逐步构建有序序列,对于未排序的元素,在已排序序列中从后向前扫描,找到对应位置插入。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析3. 快速排序算法:快速排序利用分治的思想,将序列分为左右两部分,选取基准元素,将小于基准的放在左边,大于基准的放在右边,递归地对左右部分进行排序。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析4. 归并排序算法:归并排序是一种稳定的排序算法,通过将序列分为若干子序列,分别进行排序,然后再将排好序的子序列合并成整体有序序列。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析5. 堆排序算法:堆是一种特殊的树状数据结构,堆排序利用堆的性质进行排序,通过构建大顶堆或小顶堆,并逐个将堆顶元素移出形成有序序列。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析三、实验结果分析1. 比较不同排序算法的执行时间:根据实验数据和分析,对比不同排序算法在不同数据规模下的执行时间,并针对其时间复杂度进行验证和分析。
数据结构实验C语言版
数据结构实验C语言版数据结构实验C语言版文档一、实验目的本实验旨在通过实践操作,加深对C语言中数据结构的理解,掌握常用数据结构的实现方法,提高编程能力。
二、实验内容本实验共包含以下几个章节:1.线性表1.1 顺序表的实现1.2 链表的实现1.3 环形链表的实现2.栈与队列2.1 栈的实现2.2 队列的实现3.树与图3.1 二叉树的实现与遍历3.2 图的实现与遍历4.排序与查找4.1 冒泡排序4.2 快速排序4.3 二分查找5.其他常用数据结构5.1 哈希表5.2 AVL树5.3 并查集三、实验步骤1.线性表1.1 顺序表的实现- 定义顺序表结构体 - 初始化顺序表- 插入元素- 删除元素- 查找元素1.2 链表的实现- 定义链表结构体- 初始化链表- 插入节点- 删除节点- 查找节点1.3 环形链表的实现- 定义环形链表结构体 - 初始化环形链表- 插入节点- 删除节点- 查找节点2.栈与队列2.1 栈的实现- 定义栈结构体- 初始化栈- 入栈操作- 出栈操作- 获取栈顶元素2.2 队列的实现- 定义队列结构体- 初始化队列- 入队操作- 出队操作- 获取队首元素3.树与图3.1 二叉树的实现与遍历 - 定义二叉树结构体 - 创建二叉树- 先序遍历- 中序遍历- 后序遍历3.2 图的实现与遍历- 定义图结构体- 创建图- 广度优先搜索- 深度优先搜索4.排序与查找4.1 冒泡排序- 实现冒泡排序算法- 对数组进行排序4.2 快速排序- 实现快速排序算法- 对数组进行排序4.3 二分查找- 实现二分查找算法- 在有序数组中查找指定元素5.其他常用数据结构5.1 哈希表- 定义哈希表结构体- 初始化哈希表- 插入元素- 删除元素- 查找元素5.2 AVL树- 定义AVL树结构体- 插入节点- 删除节点- 查找节点5.3 并查集- 定义并查集结构体- 初始化并查集- 合并集合- 查找根节点四、附件本文档未涉及附件。
数据结构课程设计排序实验报告
《数据结构》课程设计报告专业班级姓名学号指导教师起止时间课程设计:排序综合一、任务描述利用随机函数产生n个随机整数(20000以上),对这些数进行多种方法进行排序。
(1)至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。
并把排序后的结果保存在不同的文件中。
(2)统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。
要求:根据以上任务说明,设计程序完成功能。
二、问题分析1、功能分析分析设计课题的要求,要求编程实现以下功能:(1)随机生成N个整数,存放到线性表中;(2)起泡排序并计算所需时间;(3)简单选择排序并计算时间;(4)希尔排序并计算时间;(5)直接插入排序并计算所需时间;(6)时间效率比较。
2、数据对象分析存储数据的线性表应为顺序存储。
三、数据结构设计使用顺序表实现,有关定义如下:typedef int Status;typedef int KeyType ; //设排序码为整型量typedef int InfoType;typedef struct { //定义被排序记录结构类型KeyType key ; //排序码I nfoType otherinfo; //其它数据项} RedType ;typedef struct {RedType * r; //存储带排序记录的顺序表//r[0]作哨兵或缓冲区int length ; //顺序表的长度} SqList ; //定义顺序表类型四、功能设计(一)主控菜单设计为实现通各种排序的功能,首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
程序运行后,给出5个菜单项的内容和输入提示,如下:1.起泡排序2.简单选择排序3.希尔排序4. 直接插入排序0. 退出系统(二)程序模块结构由课题要求可将程序划分为以下几个模块(即实现程序功能所需的函数):●主控菜单项选择函数menu()●创建排序表函数InitList_Sq()●起泡排序函数Bubble_sort()●简单选择排序函数SelectSort()●希尔排序函数ShellSort();●对顺序表L进行直接插入排序函数Insertsort()(三)函数调用关系程序的主要结构(函数调用关系)如下图所示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.实验要求i.实验目的:通过编程,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
理解算法的主要思想及流程。
ii.实验内容:使用链表实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、冒泡排序(改进型冒泡排序)3、快速排序4、简单选择排序5、堆排序(小根堆)要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性iii.代码要求:1、必须要有异常处理,比如删除空链表时需要抛出异常;2、保持良好的编程的风格:代码段与段之间要有空行和缩近标识符名称应该与其代表的意义一致函数名之前应该添加注释说明该函数的功能关键代码应说明其功能3、递归程序注意调用的过程,防止栈溢出2. 程序分析通过排序算法将单链表中的数据进行由小至大(正向排序)2.1 存储结构单链表存储数据:struct node{i nt data;n ode *next;};单链表定义如下:class LinkList{private :n ode * front;public :L inkList(int a[], int n);//构造~LinkList();v oid insert(node *p, node *s); //插入……v oid turn(node*p, node*s); //交换数据v oid print(); //输出v oid InsertSort(); //插入排序v oid BubbleSort(); //pos冒泡v oid QSort(); //快速排序v oid SelectSort(); //简单选择排序n ode* Get(int i); //查找位置为i的结点v oid sift(int k, int m); //一趟堆排序v oid LinkList::QSZ(node * b, node *e); //快速排序的递归主体v oid heapsort(int n); //堆排序算法};2.2关键算法分析:1.直接插入排序:首先将待排序数据建立一个带头结点的单链表。
将单链表划分为有序区和无序区,有序区只包含一个元素节点,依次取无序区中的每一个结点,在有序区中查找待插入结点的插入位置,然后把该结点从单链表中删除,再插入到相应位置。
分析上述排序过程,需设一个工作指针p->next在无序区中指向待插入的结点,在找到插入位置后,将结点p->next插在结点s和p之间。
void LinkList::InsertSort() //将第一个元素定为初始有序区元素,由第二个元素开始依次比较{L ARGE_INTEGER t1, t2, feq;Q ueryPerformanceFrequency(&feq); //每秒跳动次数Q ueryPerformanceCounter(&t1); //测前跳动次数n ode * p = front->next; //要插入的节点的前驱w hile (p->next){node * s = front; //充分利用带头结点的单链表while (1){comparef++;if (p->next->data <s->next->data) // [P后继]比[S后继]小则插入{insert(p, s); break;}s = s->next;if (s == p) //若一趟比较结束,且不需要插入{p = p->next; break;}}}Q ueryPerformanceCounter(&t2); //测后跳动次数d ouble d = ((double)t2.QuadPart - (double)t1.QuadPart) / ((double)feq.QuadPart);//时间差秒c out << "操作时间为:" <<d << endl;}2.快速排序:主要通过轴值将数据从两端向中间进行比较,交换以实现排序。
通过递归的调用来实现整个链表数据的排序。
代码中选用了第一个元素作为轴值。
一趟排序的代码:void LinkList::QSZ(node * b, node *e){i f (b->next == e || b == e) //排序完成return;n ode * qianqu = b; //轴点前驱n ode * p = qianqu->next;w hile (p != e && p != e->next){comparef++;if (qianqu->next->data > p->next->data) //元素值小于轴点值,则将该元素插在轴点之前{if (p->next == e) //若该元素为e,则将其前驱设为ee = p;insert(p, qianqu);qianqu = qianqu->next;}else p = p->next;}Q SZ(b, qianqu); //继续处理轴点左侧链表Q SZ(qianqu->next, e); //继续处理轴点右侧链表}整个快速排序的实现:void LinkList::QSort(){L ARGE_INTEGER t1, t2, feq;Q ueryPerformanceFrequency(&feq); //每秒跳动次数Q ueryPerformanceCounter(&t1); //测前跳动次数n ode * e = front;w hile (e->next){e = e->next;}Q SZ(front, e);Q ueryPerformanceCounter(&t2); //测后跳动次数d ouble d = ((double)t2.QuadPart - (double)t1.QuadPart) / ((double)feq.QuadPart);//时间差秒c out << "操作时间为:" <<d << endl;}3.改进版的冒泡排序:通过设置pos来记录无序边界的位置以减少比较次数。
将数据从前向后两两比较,遇到顺序不对是直接交换两数据的值。
每交换一次movef+3;void LinkList::BubbleSort(){L ARGE_INTEGER t1, t2, feq;Q ueryPerformanceFrequency(&feq); //每秒跳动次数Q ueryPerformanceCounter(&t1); //测前跳动次数n ode * p = front->next;while (p->next) // 排序查找无序边界{comparef++;if (p->data > p->next->data)turn(p, p->next);p = p->next;node * pos = p; p = front->next;w hile (pos != front->next){node * bound = pos;pos = front->next;while (p->next != bound){comparef++;if (p->data > p->next->data){turn(p, p->next); pos = p->next;}p = p->next;}p = front->next;}Q ueryPerformanceCounter(&t2); //测后跳动次数d ouble d = ((double)t2.QuadPart - (double)t1.QuadPart) / ((double)feq.QuadPart);//时间差秒c out << "操作时间为:" <<d << endl;}4.选择排序:每趟排序再待排序的序列中选择关键码最小的元素,顺序添加至已排好的有序序列最后,知道全部记录排序完毕。
void LinkList::SelectSort()L ARGE_INTEGER t1, t2, feq;Q ueryPerformanceFrequency(&feq); //每秒跳动次数Q ueryPerformanceCounter(&t1); //测前跳动次数n ode * s = front;w hile (s->next->next){node * p = s;node * index = p;while (p->next){comparef++;if (p->next->data < index->next->data)index = p;p = p->next;}insert(index, s);s = s->next;}Q ueryPerformanceCounter(&t2); //测后跳动次数d ouble d = ((double)t2.QuadPart - (double)t1.QuadPart) / ((double)feq.QuadPart);//时间差秒c out << "操作时间为:" <<d << endl;}5.堆排序:利用前一趟比较的结果来减少比较次数,提高整体的效率。
其中通过链表储存了一棵树。
选择使用小根堆进行排序。
void LinkList::sift(int k, int m){i nt i = k, j = 2 * i;w hile (j <= m){comparef++;if (j<m && (Get(j)->data>Get(j + 1)->data)) j++;if (Get(i)->data < Get(j)->data) break;else{turn(Get(i), Get(j));i = j;j = 2 * i;}}}void LinkList::heapsort(int n){L ARGE_INTEGER t1, t2, feq;Q ueryPerformanceFrequency(&feq); //每秒跳动次数Q ueryPerformanceCounter(&t1); //测前跳动次数f or (int i = n / 2; i >= 1; i--)sift(i, n);f or (int i = 1; i < n; i++){turn(Get(1), Get(n - i + 1));sift(1, n - i);}Q ueryPerformanceCounter(&t2); //测后跳动次数d ouble d = ((double)t2.QuadPart - (double)t1.QuadPart) / ((double)feq.QuadPart);//时间差秒c out << "操作时间为:" <<d << endl;}其中堆排序中需要知道孩子节点和父亲节点处的值,故设置了函数获取i出的指针。