3单链表的基本操作实现(菜单的建立)
- 格式:doc
- 大小:34.50 KB
- 文档页数:5
10)调用头插法的函数,分别输入10,20,分别回车:
11)调用尾插法的函数,分别输入30,40
12)查找单链表的第四个元素:
13)主函数中传入参数,删除单链表的第一个结点:
14)主函数传入参数,删除第0个未位置的元素,程序报错:
15)最后,输出单链表中的元素:
return 0;
}
6)编译,连接,运行源代码:
7)输入8,回车,并输入8个数,用空格分隔开,根据输出信息,可以看出,链表已经拆分为两个
五、实验总结
1.单链表采用的是数据+指针的表示形式,指针域总是指向下一个结
点(结构体)的地址,因此,在内存中的地址空间可以是不连续的,操作比顺序存储更加的方便
2.单链表使用时,需要用malloc函数申请地址空间,最后,删除元
素时,使用free函数释放空间。
数据结构-单链表基本操作实现(含全部代码)今天是单链表的实现,主要实现函数如下:InitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。
最坏是O(n),即从头查找p之前的结点,然后删除p所指结点LocateElem(LinkList L,ElemType e) 参数:单链表L,元素e 功能:查找第⼀个等于e的元素,返回指针时间复杂度O(n)代码:/*Project: single linkeed list (数据结构单链表)Date: 2018/09/14Author: Frank YuInitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。
数据结构大纲知识点一、绪论。
1. 数据结构的基本概念。
- 数据、数据元素、数据项。
- 数据结构的定义(逻辑结构、存储结构、数据的运算)- 数据结构的三要素之间的关系。
2. 算法的基本概念。
- 算法的定义、特性(有穷性、确定性、可行性、输入、输出)- 算法的评价指标(时间复杂度、空间复杂度的计算方法)二、线性表。
1. 线性表的定义和基本操作。
- 线性表的逻辑结构特点(线性关系)- 线性表的基本操作(如初始化、插入、删除、查找等操作的定义)2. 顺序存储结构。
- 顺序表的定义(用数组实现线性表)- 顺序表的基本操作实现(插入、删除操作的时间复杂度分析)- 顺序表的优缺点。
3. 链式存储结构。
- 单链表的定义(结点结构,头指针、头结点的概念)- 单链表的基本操作实现(建立单链表、插入、删除、查找等操作的代码实现及时间复杂度分析)- 循环链表(与单链表的区别,操作特点)- 双向链表(结点结构,基本操作的实现及特点)三、栈和队列。
1. 栈。
- 栈的定义(后进先出的线性表)- 栈的基本操作(入栈、出栈、取栈顶元素等操作的定义)- 顺序栈的实现(存储结构,基本操作的代码实现)- 链栈的实现(与单链表的联系,基本操作的实现)- 栈的应用(表达式求值、函数调用栈等)2. 队列。
- 队列的定义(先进先出的线性表)- 队列的基本操作(入队、出队、取队头元素等操作的定义)- 顺序队列(存在的问题,如假溢出)- 循环队列的实现(存储结构,基本操作的代码实现,队空和队满的判断条件)- 链队列的实现(结点结构,基本操作的实现)- 队列的应用(如操作系统中的进程调度等)四、串。
1. 串的定义和基本操作。
- 串的概念(字符序列)- 串的基本操作(如连接、求子串、比较等操作的定义)2. 串的存储结构。
- 顺序存储结构(定长顺序存储和堆分配存储)- 链式存储结构(块链存储结构)3. 串的模式匹配算法。
- 简单的模式匹配算法(Brute - Force算法)的实现及时间复杂度分析。
2015-2016学年第二学期《算法与数据结构》课程实验报告专业软件工程学生姓名成晓伟班级软件141学号1410075094实验学时16实验教师徐秀芳信息工程学院实验一单链表的基本操作一、实验目的1.熟悉C语言上机环境,进一步掌握C语言的基本结构及特点。
2.掌握线性表的各种物理存储表示和C语言实现。
3.掌握单链表的各种主要操作的C语言实现。
4.通过实验理解线性表中的单链表存储表示与实现。
二、主要仪器及耗材普通计算机三、实验内容与要求1、用C语言编写一个单链表基本操作测试程序。
(1)初始化单链表(2)创建单链表(3)求单链表长度(4)输出单链表中每一个结点元素(5)指定位置插入某个元素(6)查找第i个结点元素的值(7)查找值为e 的结点,并返回该结点指针(8)删除第i个结点(9)销毁单链表2、实验要求(1)程序中用户可以选择上述基本操作。
程序启动后,在屏幕上可以菜单形式显示不同功能,当按下不同数字后完成指定的功能,按其他键,则显示错误后重新选择。
(2)要求用线性表的顺序存储结构,带头结点的单链表存储结构分别实现。
(3)主函数实现对基本操作功能的调用。
3、主要代码(1)初始化单链表LinkList *InitList(){ //创建一个空链表,初始化线性表LinkList *L;L=(LinkList *)malloc(sizeof(LinkList));L->next=NULL;return L;}(2)创建单链表//头插法void CreateListF(LinkList *L){LinkList *s;int i=1,a=0;while(1){printf("输入第%d个元素(0表示终止)",i++);scanf("%d",&a);if(a==0)break;s=(LinkList *)malloc(sizeof(LinkList));s->data=a;s->next=L->next;L->next=s;}}(3)求链表长度int ListLength(LinkList *L){ //求链表长度int n=0;LinkList *p=L;while(p->next!=NULL){p=p->next;n++;}return(n);}(4)在指定位置插入元素int InsertList(LinkList *L,int i,ElemType e){LinkList *p=L,*s;int j=0;while(p!=NULL&&j<i-1){p=p->next;j++;} //找出要插入的位置的前一个位置if(p==NULL){return 0;}else{s=(LinkList *)malloc(sizeof(LinkList));s->data=e;s->next=p->next;p->next=s;return 1;}}(5)输出链表void DispList(LinkList *L){ //输出链表LinkList *p=L->next;while(p!=NULL){printf("%d",p->data);p=p->next;}printf("\n");}(6)查找链表中指定元素int GetElem(LinkList *L,int i){ //查找链表中指定元素LinkList *p=L;int j=0;while(j<i&&p!=NULL){j++;p=p->next;}if(p==NULL){return 0;}else{return p->data;}}(7)查找值是e的结点并返回该指针LinkList *LocateElem(LinkList *L,ElemType e){ //查找值是e的结点并返回该指针int i=1;LinkList *p=L;while(p!=NULL)if(p->data==e) return p;}if(p==NULL){return NULL;}}(8)删除元素int ListDelete(LinkList *L,int i,ElemType *e){ //删除元素LinkList *p=L,*q;int j=0;while(p!=NULL&&j<i-1){p=p->next;j++;} //找到要删除元素地址的前一个地址if(p==NULL){ return 0;} //不能删除else{q=p->next;*e=q->data;p->next=q->next;free(q); //删除成功return 1;}}(9)销毁链表void DestroyList(LinkList *L){//销毁链表LinkList *pre=L,*p=L->next;while(p!=NULL){free(pre);pre=p;p=pre->next;}free(pre);}main函数:int main(){LinkList *L;ElemType e;int i;L=InitList();CreateListF(L);DispList(L);printf("输入要查找的元素位置:\n");scanf("%d",&i);e=GetElem(L,i);printf("%d\n",e);printf("单链表长度为:%d\n",ListLength(L));printf("输入要删除元素的位置:");scanf("%d",&i);if (i>ListLength(L)){printf("超出范围重新输入");scanf("%d",&i);}if(ListDelete(L,i,&e)==0){printf("未找到元素\n");}else DispList(L);printf("输入插入元素的位置和值:");scanf("%d%d",&i,&e);InsertList(L,i,e);DispList(L);return 0;}4、测试数据及测试结果输入:23 56 12 28 45输出:四、注意事项1、存储结构定义和基本操作尽可能用头文件实现。
单链表基本操作的实现单链表是一种常见的数据结构,它由多个节点组合而成,每个节点包含一个数据元素和一个指向下一个节点的指针。
通过指针,我们可以方便地在单链表中进行插入、删除和遍历等操作。
以下是关于单链表基本操作的实现。
1. 单链表的创建单链表的创建需要定义一个空的头结点,它的作用是方便在链表的头部进行添加和删除节点操作。
一个空的头节点可以在链表初始化的过程中进行创建。
```typedef struct Node{int data;struct Node *next;}Node;Node *createList(){Node *head = (Node*)malloc(sizeof(Node)); //创建空的头节点head->next = NULL;return head; //返回头节点的地址}```2. 单链表的插入单链表的插入可以分为在链表头部插入、在链表尾部插入和在链表中间插入三种情况。
a. 在链表头部插入节点:```void insertAtHead(Node *head, int data){Node *node = (Node*)malloc(sizeof(Node));node->data = data;node->next = head->next;head->next = node;}```b. 在链表尾部插入节点:```void insertAtTail(Node *head, int data){Node *node = (Node*)malloc(sizeof(Node));node->data = data;node->next = NULL;Node *p = head;while(p->next != NULL){p = p->next;}p->next = node;}```c. 在链表中间插入节点:```void insertAtMid(Node *head, int data, int pos){ Node *node = (Node*)malloc(sizeof(Node)); node->data = data;node->next = NULL;Node *p = head;int count = 0;while(p->next != NULL && count < pos-1){ p = p->next;count++;}if(count == pos-1){node->next = p->next;p->next = node;}else{printf("插入位置错误!");}}```3. 单链表的删除单链表的删除可以分为在链表头部删除、在链表尾部删除和在链表中间删除三种情况。
单链表的操作方法一:package ch02;(1)建立结点类Node.javapublic class Node {public Object data;//存放结点数据值public Node next;//存放后继结点//无参构造函数public Node(){ this(null,null);}//只有结点值的构造函数public Node(Object data){ this(data,null);}//带有节点值和后继结点的构造函数public Node(Object data,Node next){ this.data=data;this.next=next;}}(2)建立链表及操作LinkList.javapackage ch02;import java.util.Scanner;public class LinkList implements IList{public Node head;//单链表的头指针//构造函数初始化头结点public LinkList(){head=new Node();}//构造函数构造长度为n的单链表public LinkList(int n,boolean Order) throws Exception{ this();if(Order)create1(n); //头插法顺序建立单链表elsecreate2(n); //尾插法逆序建立单链表}//头插法顺序建立单链表public void create1(int n) throws Exception{Scanner sc=new Scanner(System.in);System.out.println("请输入结点的数据(头插法):”);for(int i=0;i<n;i++){insert(0,sc.next());}}//尾插法逆序建立单链表public void create2(int n) throws Exception{Scanner sc=new Scanner(System.in);System. out.println("请输入结点的数据(尾插法):");for(int i=0;i<n;i++){insert(length(),sc.next());}}//将链表置空public void clear(){head.data=null;head.next=null;}//判断链表是否为空public boolean isEmpty(){return head.next==null;}//返回链表长度public int length(){Node p=head.next;int length=0;while(p!=null){p=p.next;length++;//返回P不空长度length加1}return length;}//读取并返回第i个位置的数据元素public Object get(int i) throws Exception {Node p=head.next;int j;//从首结点开始向后查找,直到9指向第i个结点或者p为nullfor(j=0;j<i&&p!=null;j++){ p=p.next;}if(j>i||p==null)//i不合法时抛出异常throw new Exception("第"+i+”个数据元素不存在”);return p.data;}//插入乂作为第i个元素public void insert(int i, Object x) throws Exception{ Node p=head;int j=-1;//寻找第i个结点的前驱i-1while(p!=null&&j<i-1){p=p.next;j++;}if(j>i-l||p==null)//i不合法时抛出异常throw new Exception("插入位置不合法”);Node s=new Node(x);s.next=p.next;p.next=s;}//删除第i个元素public void remove(int i) throws Exception{ Node p=head;int j=-1;while(p!=null&&j<i-1){//寻找第i-1 个节点p=p.next;j++;}if(j>i-1||p.next==null)throw new Exception("删除位置不合法”);p.next=p.next.next;}//返回元素x首次出现的位序号public int indexOf(Object x) {Node p=head.next;int j=0;while(p!=null&&!p.data.equals(x)){p=p.next;j++;if(p!=null)return j;elsereturn -1;}public void display(){Node p=head.next;while(p!=null){if(p.next==null)System.out.print(p.data);elseSystem.out.print(p.data+"f );p=p.next;}}}(3)建立测试类Test.javappublic class test {public static void main(String[] args) throws Exception { // TODO Auto-generated method stubScanner sc=new Scanner(System.in);boolean or;int xz,xx;System.out.println("请选择插入的方法:0、头插法,1、尾插法");xz=sc.nextInt();if(xz!=0)or=true;elseor=false;System. out.println("请插入的结点的个数:”);xx=sc.nextInt();LinkList L=new LinkList(xx,or);System.out.println("建立的链表为:");L.display();System.out.println();System.out.println("链表的长度:"+L.length());System. out.println(”请输入查找的结点的数据:”);Object x=sc.next();int position=L.indexOf(x);System.out.println("结点的数据为:"+x+"的位置为:"+position); System. out.println("请输入删除的结点的位置:”);int sr=sc.nextInt();L.remove(sr);L.display();System.out.println();System.out.println("链表的长度:"+L.length()); }品P rob I em & J a vs d oc / Declaration Q Error Log 里Con sole-M、、■=:termin8ted> test [3] [Java Application] C U &ert\Ad im i n i st rat o r\Ap p Data\L o cs I请选择插入.的方法:0、头插法,lv星插法请插入的特点的个数:请愉入结点的颓据(尾插法):A B C E D F建立的旌表为;A+B T C+E T D+F链表的长度:6请输入查找的结点的数据:结点的数据为:E的位置为:3请输入删除的结点的位置,R+B T E+DW道表的长度:S方法二(引入get和set方法)Package sy;import java.util.Scanner;//单链表的结点类public class Node {private Object data; //存放结点值private Node next; //后继结点的引用public Node() { //无参数时的构造函数this(null, null);}public Node(Object data) { // 构造值为data 的结点this(data, null);}public Node(Object data, Node next) {//构造值为data 和next 的结点构造函数this.data = data;this.next = next;}public Object getData() { return data;}public void setData(Object data) {this.data = data;}public Node getNext() { return next;public void setNext(Node next) { this.next = next;}}//实现链表的基本操作类public class LinkList {Node head=new Node();//生成一个带头结点的空链表//根据输入的一系列整数,以0标志结束,用头插法建立单链表public void creat() throws Exception {Scanner sc = new Scanner(System.in); //构造用于输入的对象for (int x=sc.nextInt(); x!=0; x=sc.nextInt()) //输入若干个数据元素的值(以0结束) insert(0, x);//生成新结点,插入到表头}//返回带头结点的单链表中第i个结点的数据域的值。
算法练习题一、基础算法1. 编写一个程序,实现一个冒泡排序算法。
2. 实现一个选择排序算法。
3. 实现一个插入排序算法。
4. 编写一个函数,计算一个整数数组中的最大值和最小值。
5. 编写一个函数,实现二分查找算法。
6. 编写一个函数,实现快速排序算法。
7. 编写一个函数,判断一个整数是否为素数。
8. 编写一个函数,实现反转一个整数数组。
9. 编写一个函数,计算两个整数数组的交集。
10. 编写一个函数,判断一个字符串是否为回文。
二、数据结构11. 实现一个单链表的基本操作,包括插入、删除、查找。
12. 实现一个双向链表的基本操作,包括插入、删除、查找。
13. 实现一个栈的基本操作,包括压栈、出栈、查看栈顶元素。
14. 实现一个队列的基本操作,包括入队、出队、查看队首元素。
15. 实现一个二叉树的基本操作,包括插入、删除、查找。
16. 实现一个二叉搜索树的基本操作,包括插入、删除、查找。
17. 实现一个哈希表的基本操作,包括插入、删除、查找。
三、搜索与图论18. 编写一个程序,实现深度优先搜索(DFS)算法。
19. 编写一个程序,实现广度优先搜索(BFS)算法。
20. 编写一个程序,求解迷宫问题。
21. 编写一个程序,计算一个有向图的拓扑排序。
22. 编写一个程序,计算一个无向图的欧拉回路。
23. 编写一个程序,计算一个加权无向图的最小树(Prim算法)。
24. 编写一个程序,计算一个加权有向图的最短路径(Dijkstra算法)。
25. 编写一个程序,计算一个加权有向图的所有顶点对的最短路径(Floyd算法)。
四、动态规划26. 编写一个程序,实现背包问题。
27. 编写一个程序,计算最长公共子序列(LCS)。
28. 编写一个程序,计算最长递增子序列(LIS)。
29. 编写一个程序,实现编辑距离(Levenshtein距离)。
30. 编写一个程序,实现硬币找零问题。
31. 编写一个程序,实现矩阵链乘问题。
一、实训背景随着计算机科学和信息技术的发展,算法作为计算机程序的核心,其重要性日益凸显。
为了提高学生的算法设计、实现和分析能力,我们开展了算法开发实训课程。
本次实训旨在让学生通过实际项目开发,深入了解算法原理,提高算法应用能力。
二、实训目标1. 熟悉常用算法的基本原理和实现方法;2. 能够根据实际问题选择合适的算法;3. 掌握算法分析、调试和优化方法;4. 培养团队协作和沟通能力。
三、实训内容1. 实训项目:基于单链表的排序算法实现项目描述:设计一个单链表,并实现插入排序、归并排序和快速排序三种排序算法,对链表中的元素进行排序。
2. 实训步骤(1)设计单链表节点结构体,包含数据域和指针域;(2)实现单链表的创建、插入、删除和遍历等基本操作;(3)实现插入排序、归并排序和快速排序三种排序算法;(4)测试排序算法的性能,对比分析不同排序算法的优缺点;(5)编写测试用例,验证排序算法的正确性。
四、实训过程1. 单链表节点结构体设计```ctypedef struct Node {int data;struct Node next;} Node;```2. 单链表基本操作实现```c// 创建单链表Node createList() {Node head = (Node)malloc(sizeof(Node));if (head == NULL) {return NULL;}head->next = NULL;return head;}// 插入节点void insertNode(Node head, int data) {Node newNode = (Node)malloc(sizeof(Node)); if (newNode == NULL) {return;}newNode->data = data;newNode->next = head->next;head->next = newNode;// 删除节点void deleteNode(Node head, int data) {Node temp = head;Node prev = NULL;while (temp != NULL && temp->data != data) { prev = temp;temp = temp->next;}if (temp == NULL) {return;}prev->next = temp->next;free(temp);}// 遍历链表void traverseList(Node head) {Node temp = head->next;while (temp != NULL) {printf("%d ", temp->data);temp = temp->next;}printf("\n");```3. 排序算法实现(1)插入排序```cvoid insertionSort(Node head) {Node sorted = NULL;Node current = head->next;Node prev = NULL;Node temp = NULL;while (current != NULL) {temp = current->next;current->next = NULL;if (sorted == NULL || sorted->data >= current->data) {current->next = sorted;sorted = current;} else {prev = sorted;while (prev->next != NULL && prev->next->data < current->data) {prev = prev->next;}current->next = prev->next;prev->next = current;}current = temp;}head->next = sorted;}```(2)归并排序```cNode merge(Node left, Node right) {Node result = NULL;if (left == NULL)return right;else if (right == NULL)return left;if (left->data <= right->data) {result = left;result->next = merge(left->next, right); } else {result = right;result->next = merge(left, right->next); }return result;}void mergeSort(Node head) {if (head == NULL || head->next == NULL)return;Node slow = head;Node fast = head;Node temp = NULL;while (fast != NULL && fast->next != NULL) { temp = slow;slow = slow->next;fast = fast->next->next;}temp->next = NULL;Node left = mergeSort(head);Node right = mergeSort(slow);head = merge(left, right);}```(3)快速排序```cint partition(Node head, int low, int high) {int pivot = head->next->data;Node i = head;Node j = head->next->next;while (j != NULL) {if (j->data < pivot) {i = i->next;int t = i->data;i->data = j->data;j->data = t;}j = j->next;}int t = i->data;i->data = head->next->data;head->next->data = t;return i->data;}void quickSort(Node head, int low, int high) { if (low < high) {int pi = partition(head, low, high); quickSort(head, low, pi - 1);quickSort(head, pi + 1, high);}}```4. 测试与优化通过编写测试用例,验证排序算法的正确性。