线性表学习1

news/2024/10/19 9:48:04
  • 线性结构
    若结构是非空有限集,则有且仅有一个开始结点和一个终端结点,并且除了首尾节点外所有结点都最多只有一个直接前趋和一个直接后继。 可表示为:(a1,a2,a3,...)
    特点:只有一个首结点和尾结点
    本质特征:除首尾结点外,其他结点只有一个直接前驱和一个直
    接后继。
    简言之,线性结构反映结点间的逻辑关系是二对一(1:1)的
    线性结构包括:线性表、 堆栈、 队列、 字符串、 数组
    等,其中最典型、 最常用的是线性表

线性表

线性表逻辑结构

alt text

PS:空表分配了内存空间但是没有元素,不是不存在这个表

线性表的顺序表示和逻辑实现

顺序表的表示

线性表的顺序表的表示又叫顺序存储结构顺序映像
alt text

线性表顺序存储的特点

  1. 逻辑上相邻的数据元素,其物理存储上也相邻;
  2. 若已知表中首元素在存储器中的位置则其他元素存放位置亦可求出
    alt text

LOC(ai)=LOC(a0)+L*(i)

顺序表的实现

(增删改查)

  1. 修改
    alt text

O(1)指的是对同一个元素只进行一次操作

  1. 增加
    遍历是从第i个到第L.length个元素
    在表的第i个元素前面插入一个元素
    alt text

  2. 删除
    删除线性表的第个位置上的元素
    alt text

  3. 清空和删除表

  4. 排序

  5. 查找
    下标查找即可

顺序表的运算效率分析

alt text

alt text

同理可证: 顺序表删除一元素的时间效率(时间复杂度)为
T (n)=(n-1)/2约等于o(n)

空间复杂度:0=o(1),因为没有使用辅助数据

深入讨论

顺序表各种操作的通式如何写??

写了一个晚上,思路不难,就是一些语法细节要注意(C语言基础不够牢导致的)

#include <stdio.h>
#include <stdlib.h>
typedef struct{int *numlist;int length;}chatDemo;
//冒泡排序
void bubble(int *arr,int length){int temp=0;for(int i=0;i<length-1;i++){for(int j=0;j<length-i-1;j++){if(arr[j]>arr[j+1]){temp=arr[j+1];arr[j+1]=arr[j];arr[j]=temp;}}}}
void search(chatDemo list,int tofind){//二分法查找int start=0;int end=list.length-1;int mid;while(start<=end){mid=(start+end)/2;if(tofind>list.numlist[mid]){start=mid;}else if(tofind<list.numlist[mid]){end=mid;}else if(tofind==list.numlist[mid]){printf("the index is %d",mid);return;}}printf("404 not found");
}
void del(chatDemo *list,int position){if(position<0||position>=list->length){printf("OutoffpositionError");return;}for(int i=position;i<list->length;i++){list->numlist[i-1]=list->numlist[i];}list->numlist[list->length-1]=0;list->length-=1;list->numlist=(int*)realloc(list->numlist,list->length*sizeof(int));printf("after del length:%d\n",list->length);
}
void add(chatDemo *list,int position,int addnum){if(position<1||position>list->length){printf("OutoffpositionError");return;}list->length+=1;list->numlist=(int*)realloc(list->numlist,list->length*(sizeof(int)));list->numlist[list->length-1]=0;for(int i=list->length-1;i>position-1;i--){list->numlist[i]=list->numlist[i-1];}list->numlist[position-1]=addnum;printf("after add length:%d\n",list->length);
}
int main(){chatDemo demo;demo.length=10;demo.numlist=(int*)calloc(demo.length,sizeof(int));int initial_values[] = {9, 2, 8, 3, 1, 4, 5, 6, 10, 7};for (int i = 0; i < demo.length; i++) {demo.numlist[i] = initial_values[i];}bubble(demo.numlist,demo.length);printf("排序后数组\n");for (int i = 0; i < demo.length; i++) {printf("%d\n",demo.numlist[i]);}del(&demo,4);printf("数组长度是%d\n",demo.length);for(int i=0;i<demo.length;i++){printf("%d\n",demo.numlist[i]);}add(&demo,4,4);printf("数组长度是%d\n",demo.length);for(int i=0;i<demo.length;i++){printf("%d\n",demo.numlist[i]);}search(demo,8);free(demo.numlist);return 0;
}

抽象数据类型

线性表的链式表示和逻辑实现

#include <stdio.h>
#include <stdlib.h>
#include<assert.h>typedef struct Node
{int data;      //数据域struct Node *next;  //指针域,构建递归结构
}Node;
typedef struct {Node *head;  // 头指针Node *tail;size_t length;// 尾指针
} List;
void InitList(List *list);//初始化
void push_tail(List *list,int x);//尾插
void push_head(List *list,int x);//头插
void show_list(List *list);//打印链表
void delAimval(List *list,int x,int ifone);//删除指定元素
void add(List *list,int x,int position,int fa);//指定位置前或后插入
void reverse(List*list);//逆序
Node *find(List *list,int x);//查找元素第一次出现位置,修改//
int main(){int numlist[]={0,1,2,5,5,6,7,8,9,8,5,2,1,1};int len=(int)(sizeof(numlist)/sizeof(int));int i=0;List demo,demox;InitList(&demo);InitList(&demox);while(i<len){push_tail(&demo,numlist[i++]);}printf("尾插法创建\n");show_list(&demo);i--;while(i>=0){push_head(&demox,numlist[i--]);}printf("头插法创建\n");show_list(&demox);reverse(&demox);printf("逆序后\n");show_list(&demox);delAimval(&demox,5,1);printf("删除一次指定元素5后\n");show_list(&demox);delAimval(&demox,5,0);printf("删除全部指定元素5后\n");show_list(&demox);printf("后插元素\n");add(&demox,99,6,1);show_list(&demox);printf("前插元素\n");add(&demox,99,6,0);show_list(&demox);find(&demox,2);return 0;
}
//初始化
void InitList(List *list)
{Node* headNode=(Node*)malloc(sizeof(Node));//此时头指针指向头节点list->head=headNode;assert(list->head!=NULL);list->head->next=NULL;list->tail = list->head; //尾指针也一起指向头节点。list->length=0;}
void push_head(List *list,int x){Node *new_node=(Node*)malloc(sizeof(Node));assert(new_node!=NULL);new_node->data=x;new_node->next=NULL;//第一个节点的插入需要改尾指针的指向if(list->length==0){list->tail=new_node;}new_node->next=list->head->next;list->head->next=new_node;list->length++;}
void push_tail(List *list,int x){Node *new_node=(Node*)malloc(sizeof(Node));assert(new_node!=NULL);new_node->data=x;new_node->next=NULL;// 将当前尾节点的next指向新节点list->tail->next = new_node;// 更新尾指针list->tail = new_node;list->length++;
}
void show_list(List *list)
{Node *p = list->head->next;while(p!=NULL){printf("%d-->",p->data);p=p->next;
}
printf("NULL\n");
}
Node *find(List *list,int x){int j=1;Node *p=list->head->next;while(p){if(p->data==x){//可以同时修改元素,这里就不实现了break;}else{j++;p=p->next;}}printf("%d是第%d个元素",x,j);return p;
}
void delAimval(List*list,int x,int ifone){Node *p=list->head;while(p!=NULL&&p->next!=NULL){if(p->next->data==x){Node *p2=p->next->next;Node *p1=p->next;p->next=p2;free(p1);list->length--;if(ifone==1){break;}else if(ifone==0){p=list->head;continue;}else{printf("ffsr");}}else{p=p->next;}}
}
void add(List *list,int x,int position,int fa){int j=1;Node *new_node=(Node*)malloc(sizeof(Node));new_node->data=x;if(position<1||position>(int)list->length){printf("DIANLAO");return;}if(fa==0){//前插Node *p=list->head;while(p&&p->next){if(j==position){new_node->next=p->next;p->next=new_node;list->length++;break;}else{p=p->next;j++;}}}else if(fa==1){//后插Node *p=list->head->next;while(p){if(j==position){new_node->next=p->next;p->next=new_node;list->length++;break;}else{p=p->next;j++;}}}
}
void reverse(List*list){Node* previous=NULL;Node* current=list->head->next;Node*next=NULL;while(current!=NULL){next=current->next;// 保存下一个节点current->next=previous;// 当前节点指向前一个节点previous=current;// 前一个节点移动到当前节点current=next;// 当前节点移动到下一个节点}list->head->next=previous;
}

运行结果

alt text

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73343.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

学习 gradle 基础

简介 Gradle 的优势一款最新的,功能最强大的构建工具,用它逼格更高 使用 Groovy 或者 Kotlin 代替 XML,使用程序代替传统的 XML 配置,项目构建更灵活 丰富的第三方插件,让你随心所欲使用 完善 Android,Java 开发技术体系下载和安装 官网地址 https://services.gradle.org…

AutoResetEvent双向信号(生产者和消费者)例子

AutoResetEvent是一个非常有用的线程同步机制,尤其是在处理生产者和消费者问题的时候,尤其适用。本随笔记录下生产者和消费者一对一问题的两种写法并进行代码执行逻辑的分析,来加深对AutoResetEvent的理解。 写法一:internal class Program {public static AutoResetEvent …

数据采集和融合技术作业1

作业① 1)用requests和BeautifulSoup库方法定向爬取给定网址的数据,屏幕打印爬取的大学排名信息。 a、主要代码解析 该函数从获取的JSON数据中提取前 num 名大学的信息,并将这些信息存储到 ulist 列表中,同时格式化输出这些大学的排名信息 def printUnivList(ulist, html, …

沃顿商学院商业人工智能笔记-六-

沃顿商学院商业人工智能笔记(六) P46:12_简介.zh_en - GPT中英字幕课程资源 - BV1Ju4y157dK 嗨,我是迈克尔罗伯茨。我是威廉H罗伯茨教授。 我是宾夕法尼亚大学沃顿商学院的金融学劳伦斯教授。 在这一系列视频中,我们将讨论金融、机器学习。以及人工智能。因此,当我想到金…

沃顿商学院商业人工智能笔记-九-

沃顿商学院商业人工智能笔记(九) P82:19_更广泛的隐私和伦理问题.zh_en - GPT中英字幕课程资源 - BV1Ju4y157dK 所以让我们讨论一下关于使用数据科学和人工智能的一些更广泛的问题。一般来说,在工作场所管理人际关系。这些是伦理问题,也是隐私问题。 所以让我们谈谈这些问…

沃顿商学院商业人工智能笔记-三-

沃顿商学院商业人工智能笔记(三) P123:22_AI的风险.zh_en - GPT中英字幕课程资源 - BV1Ju4y157dK 在这次讲座中,我们将讨论AI的一些风险。我将以一个简单的统计风险开始,它有重要的管理意义。 然后我会谈论社会和伦理风险。 所以我想讨论的第一个风险是过拟合风险。 现在,…

沃顿商学院全套笔记-三十三-

沃顿商学院全套笔记(三十三) 沃顿商学院《实现个人和职业成功(成功、沟通能力、影响力)|Achieving Personal and Professional Success》中英字幕 - P8:7_成功的两面.zh_en - GPT中英字幕课程资源 - BV1VH4y1J7Zk When you unpack the word success for the first time,…

沃顿商学院全套笔记-三十二-

沃顿商学院全套笔记(三十二) 沃顿商学院《实现个人和职业成功(成功、沟通能力、影响力)|Achieving Personal and Professional Success》中英字幕 - P68:4_从德梅洛获取的启示.zh_en - GPT中英字幕课程资源 - BV1VH4y1J7Zk What can we learn about power and influence …