当前位置:文档之家› 数据结构 单链表详解

数据结构 单链表详解

数据结构的概念:数据的逻辑结构+ 数据的存储结构+ 数据的操作;数据的数值:=====》数据===》数值型数据整形浮点数ASCII非数值型数据图片声音视频字符=====》数据元素=====》基本项组成(字段,域,属性)的记录。

数据的结构:逻辑结构----》线性结构(线性表,栈,队列)----》顺序结构----》链式结构----》非线性结构(树,二叉树,图)----》顺序结构----》链式结构存储结构-----》顺序存储-----》链式存储-----》索引存储-----》哈希存储==散列存储数据的操作:增删改查DS ====》数据结构===》DS = (D,R);数据结构中算法:1、定义:有穷规则的有序集合。

2、特性:有穷性确定性输入输出3、算法效率的衡量时间复杂度计算===》算法中可执行依据的频度之和,记为:T(n)。

是时间的一种估计值不是准确值。

计算结果的分析:1 将最终结果的多项式中常数项去掉2 只保留所有多项式中最高阶的项3 最后的最高阶项要去掉其常数项时间复杂度的量级关系:常量阶====》对数阶===》线性阶===》线性对数阶====》平方阶===》立方阶===》指数阶以上关系可以根据曲线图来判断算法对时间复杂度的要求空间复杂度计算====》算法执行过程中所占用的存储空间的量级,记为:D(n)。

计算方法是在运行过程中申请的动态内存的量级计算。

/////////////////////////////////////////////////////////////////////////////////////////////////线性表顺序存储====》顺序表(数组)链式存储====》单链表特征:对于非空表,a0是表头没有前驱。

an-1 是表尾没有后继ai的每个元素都有一个直接前驱和直接后继基本操作:创建表=====》增加元素====》删除元素====》改变元素值====》查询元素1、顺序表的操作1.1 创建顺序表=====》定义个指定类型的数组====》int a[100] ={0};#define N 10typedef int datatype;typedef struct{datatype data[N]; ///表的存储空间int last; ///表尾下标,表示当前顺序表的最后存储的位置}sqlist,*sqlink; /// sqlist 表结构类型sqlink 表结构指针sqlink = sqlist *sqlist sq; ////栈区sqlink psq = (sqlink)malloc(sizeof(sqlist));///堆区1.2 增加顺序表元素操作(从头开始增加,插入)////从头增加sq.data[st] = values;st++;///插入void insert(L, x,i);====>L 就是顺序表,x 要插入的数据= values, i是要插入的位置{///防边界处理for(j=st;j>i;j--){sq.data[j] = sq.data[j-1];}sq.data[i] = x;st++;}1.3 删除顺序表操作(从尾部删除,从中间位置删除)void delete(L,i) ====>L 就是要删除的顺序表,i 要删除的位置{///防边界处理for(j=i;j<st;j++){sq.data[j] = sq.data[j+1];}st--;}1.4 改变顺序表中的值void change(L,x,i) ////i 是数组元素的下标{sq.data[i] = x;}void change_vlue(L ,x1,x2) ////根据元素的值修改{for(j=0;j<st;j++){if(sq.data[j] == x1)sq.data[j] = x2;}}1.5 查询顺序表中的值void select(L,i){printf("%d \n",sq.data[i]);}1.6 判断表示空,还是满。

练习:根据以上提示,尝试编写简单的顺表常规操作,1、自动输入若干个数据并存储到顺序表中。

2、简单删除指定的表中数据3、修改指定的表中数据4、查询指定下标的数据值特点:1、顺序表的存储方便,遍历数据方便。

2、插入和删除效率较低。

3、每次要明确的连续地址空间,且一旦定义就不能修改。

2、单链表的操作链表本身有自己的结构,所有的链表成员都是结点。

每个结点应该至少有两个域:数据域+ 指针域基本结构:typedef int datatype;typedef stuct _node{datatype data;struct _node *next;}linknode,*linklist;基本操作:创建单链表====》linklist list = (linklist)malloc(sizeof(linknode));===>头结点list->data = 0;list->next = NULL;创建结点====》linknode * create_node(datatype value){linknode *newnode = (linknode *)malloc(sizeof(linknode));newnode->data = value;newnode->next = NULL;return newnode;}链表的插入(增加)1、头插入法===》每次新创建的结点总是头结点的下一跳int insert_head(linklist L ,linknode * pnode){linklist tmp = L;pnode->next = tmp->next;tmp->next = pnode;tmp->data ++;}2、尾插入法===》每次新创建的结点都是最后一个结点int insert_tail(linklist L ,linknode * pnode){linklist tmp = L;while(tmp->next){tmp= tmp->next;}tmp->next = pnode;tmp->data ++;}显示链表中所有节点数据:void show_linklist(linklist L){linklist tmp = L;while(tmp->next){tmp= tmp->next;printf("%d \n",tmp->data);}}练习:自动创建单链表并依次新建10个子节点分别用头插入法和尾插入法的方法将节点增加到链表中,最后用show_linklist函数遍历单链表并显示每个结点的数据域的值。

链表的删除int delete_link(linklist L ,datatype value){linklist tmp = L;linklist tmp2 = L->next;int flag = 0;while(tmp2){if(tmp2->data == value){tmp->next = tmp2->next;free(tmp2);flag = 1;}else{tmp = tmp->next;tmp2 = tmp2->next;}}if(flag)return 0;elsereturn -1;}链表的改值int delete_link(linklist L ,datatype value1,datatype value2){linklist tmp2 = L->next;while(tmp2){if(tmp2->data == value1){tmp2->data = value2;}else{tmp2 = tmp2->next;}}}链表的查询1、查询总个数=====>pritnf("%d",L->data);2、根据数据值查询对应的地址void Locate(linklist L ,datatype value)===>返回值是地址链表资源释放void free_linklist(linklist L){linklist tmp =NULL;while(L){tmp = L;L= L->next;free(tmp);}}特点:1、插入和删除效率高2、遍历效率低3、需要动态申请内存,可能存在内存泄露。

作业:提示用户任意输入10个整形数字,用链表方式存储。

输入完毕后可以任意删除其中三个数字,并将每次删除后的链表数据打印输出。

相关主题