专题1,2 数据结构(学习笔记)

国嵌数据结构视频 学习笔记


专题1.内行看门道.



第一节.1进阶高手的大门_


 1数据结构的教学目标.
   理论与实践相结合,数据结构比较难,
   数据结构分成专题的形式,计算机现在是应用.
   不是搞理论的.
  
 2进阶高手的大门?
 什么是高手?语言是要靠应用的,学了就要用,
 学了不用就是废物.计算机是用来处理数据,计算.
 
3. 程序的灵魂---算法.
 审批程序的灵魂.
   什么才是好程序,
   1.可读性,
   2.性能比,
   
4. 问:什么是高手?学习了C语言,还是写不出程序,为什么?
    因为你还没理解程序.
   问题1:为什么有各种各样的程序存在?
   网上有大把的程序例子,播放程序,聊天程序,有那么多程序,
   为什么还有人不断继续开发新的程序, 就播放程序,
   百度开发,QQ在出,讯雷也在出, 为什么他们还要出?
   为什么有那么的程序存在?那就要了解程序的本质.
   这是什么问题啊,没有逻辑.
   
5:程序的本质是什么?
 答: 1.程序的本质,就是为了解决实际问题而存在的.
         从本质上而言,程序是解决问题的步骤描述.
 
6.C语言从main开始运行的,一句一句代码运行.


7.怎么把大象放在冰箱.
1.打开冰箱门.  Elephan * e = getElep();
2.把大象放进去. int f = open("fridga");
3.关上冰箱门.   put(f,e); close(f);
这就是解决问题的步骤.问题的解决步骤,从而导出程序的逻辑.
如果学了C语言,写不出程序,那是因为你遇到实现的问题大小了.
你上机,练习的时间太少,
开发程序的前提条件,深入分析遇到的问题.导出程序逻辑.
所先我们首先理解实际问题.
a. 确认问题类型.
如:数值计划,求最小值个数
b. 确认求解的步骤.
    如:打开文件,读数据,关闭文件,计算和.
附:如何判断求解步骤的好坏.
 
7.
 在生活中解决一个问题的方法,往往不只一种.
 所以通过程序去求解的问题的答案不只一种,
 我们如何判断求解步骤的好坏.
 
 解决方法的对比.
 求 1+2+....n的和.
  三种方法:
   1.方法1. 先申请N个空间,把这N个数放进去,然后N个数值 .
   2.方法2. 进行使用for循环累加.
   3.方法3. 直接使用数学公式. (1+n)*(n/2);
 
使用方法1的人是比较死板的人.
使用方法2的人是比较平常的人.
使用方法3的人是thinkabout的人.善于思考的人.


8.程序评监初探.
81.尽量少的内存空间解决问题.
82.尽量少的步骤解决问题.     
  优秀的开发者需要追求代码的高"性价比"
  但是这也不是绝对了,有时候在那个提高代码的可读性的情况下
  会牺牲程序的空间,与步骤.
 
9.小结:
91.程序是为了具体问题而存在的.
92.程序需要围绕问题的解决进行设计
  93.同一个问题可以有多种解决方法.
 
10 是否有可量化的方法判断程序的好坏?
 有没有?
 
10 如果提高写程序的能力?
 如果去判断一个程序的好坏?
 
 最后一句,程序一定要围绕问题而且设计.
 
 
第2节.数据的艺术.
 1.数据的起源.
    计算机一开始是解决数值计算的问题.
    后来发展解决生活中的问题.
    现实生活中的问题涉及不同个体间的复杂联系.
    需要在计算机程序中描述生活中个体间的联系.
    数据结构主要研究非数值计算程序问题中的操作对象以及它们
    之间的关系.
      
   一句话,数据结构是描述操作对象之间的关系的一门学科.
   我们如何理解数据结构的数据了?
    关键的概念.
    1. 数据  = 程序的操作对象,用于描述客观的事物 
    2. 数据的特点:
        可以输入到计算机,可以被计算机处理.
    数据是一个抽象的开概念,将其进行分类后得到程序设计语言中的类型
    如:int,float,char等等.
    
    数据结构的数据分类?分什么类? int,char ,float???
    3数据元素  -- 组成数据的基本单位.
          数据项----个数据元素由若干个数据项组成.
    4.数据对象   -- 性质相同的数据元素的集合.
     
    5.数据元素之间不是独立,存在的特点的关系,这是关系即结构.
    6.数据结构指数据对象中数据元素之间的关系.
     如:数组中各个元素之间存在固定的线性关系.
       编写一个好程序之前,必须分析待处理问题中各个对象的特征,以及对象
       之间的关系.
       数组就是一种数据结构,一种线性的数据结构.
       在用却不知道.百姓日用而不知.
    
    数据结构就是研究数据之间的关系.
    逻辑结构
       集合结构: 数据元素之间没有特别的关系,ji同属相同集合.
       线性关系: 数据元素之间是一对一的关系. 如:数组
       树形结构: 数据元素之间存在一对多的层次的关系.
       图形结构: 数据元素之间是多对多的关系.(还是有用的,比较腾讯的好友推算功能,玩游戏的路径寻找。)
       
       一个图片来表示:
       
     物理结构: 逻辑结构在计算机中的存储形式 
     顺序存储结构: 将数据存储在地址连续的存储单元里.(对应线性存储)
     链式存储结构: 将数据存储在任意存储单元里,
                    通过保存地址的方式找到相关取的数据元素.(对应树图的存储)


     小结
      
                      数据
          数据对象               数据对象
     数据元素  数据元素     数据元素   数据元素 
     
     数据结构是相互之间存在一种或多种
     特定关系的数据元素的集合.
     
     按照视点的不同,数据结构可以分成
     逻辑结构(集合,线性,树形,图形)
     物理结构( 顺序,链式结构)
    
第3节,程序的灵魂-算法.
 
 1.算法与数据结构有什么关系?
     要搞清楚这个问题,
    程序是否越短越好?是否别人看不懂就证明自己很厉害.
    不是
   
  数据结构与算法.
   a.数据结构只是静态的描述了数据元素之间的关系.
   b.高效的程序需要在数据结构的基础上设计和选择算法.
  
    高效的程序 a.恰当的数据结构
               b.合适的算法
              
   数据结构与算法是两门课程,
   本课程主要是讲数据结构,但是算法与数据结构是
   联系在一起,再能更加好解决问题.
   现在是重点是数据结构,引进算法,其实两者不可分开 的.
   但是一起讲,内容太多了,再加上算法涉及的
   知识太多,涉及一些数学方面的知道 .
   
   
   算法的定义
     a.算法是特点问题求解步骤的描述.
     b.计算机中表现为指令的有限序列.
        算法是独立存在的一种解决问题的方法和思想.
         对于算法而言,语言并不重要,重要的是思想.
         
    语言重要吗?语言也是重要,适合,每种语言都有自己的特点.
    针对于应用,开发linux驱动,C语言比较适合,但是开发网站就不适合了.
    
    算法的特征
     1. 输入:具有0个或多个输入
     2.输出:算法到少有1个或多个输出.
     3.有穷性: 算法在有限的步骤之后会自动解除而不会无限循环.
     4.确定性:算法中的每一步都有确定的含义,不会出现二义性.
     5.可行性:算法的每一步都是可行的.
     
     程序包含了各种算法,但是程序不是算法,这些概念可以理解,也可以不理解.
    
  算法设计的准则
  1.正确性
 a:算法对于合法数据能够得到满足要求的结果.
 b:算法能够处理非法输入,并得到合理的结果.
 c:算法对于边界数据和压力数据都能得到满足要求的结构.
   注意:正确性是算法是需要满足的基本的准则,但是作为计算机程序,
       不可能无限制的满足这条准则.
       例如,我们有一个排序法,我输入1000亿个数据去排序,就出问题了.
  2.可读性: 算法要方便阅读,理解和交流
  3.健壮性:算法不应该产生莫名其妙的结果.
  4.高性价比:利用最少的时间和资源得到满足要求的结果.
       注意:算法可读性是最容易被忽视,然而,程序是写给人看的,而不是计算机.
   
   小结
   1:算法是 为了解决实际问题而设计的.
   2.数据结构是算法需要处理的问题载体.
   3.数据结构与算法相缚相成的.
     程序 =  数据结构 + 算法.
     
第4集 审批程序的灵魂.
     算法效率的度量
     1.事后统计法:比较不同算法对一组输入数据的运行处理时间
     2.缺陷:为了获得不同算法的运行时间必须编写相应程序
            运行时间严重依赖硬件以及运行时的环境因素.
            算法的测试数据的选取相当困难.
            
        事后统计法虽然直观,但是实施困难且缺陷多,一般不于考虑.
        
        
     3.事前分析估算:依据统计的方法对算法效率进行估算.
     4.影响算法效率的主要因素
         算法采用的策略和方法
         问题的输入规模
         编译器所产生的代码
         计算机执行速度.
         
    5.算法的效率 与 算法本身与问题规模相关.
        ---算法本身就是解题步骤 计算机语句
        ---问题规模就是N
 
   
   算法的效率的度量,
   简单的估算,计算执行的指令.
   关键部分,操作数量为n*n.
    随意问题规模n的增大,它们操作数量的差异会越来越大,因
    此际算法在时间效率上差异也会变得非常明显.
    
    算法效率的度量.
    判断一个算法的效率时,往往只需要关注操作数量的最高次项
    其它次要项和常数项可以忽略.
     
     算法效率的度量
        大O表示法
          1. 算法效率严重依赖操作数量
          2. 在判断时首先关注操作数量的最高项.
          3. 操作数量的估估算可以作为时间复杂度的估算.
          
            O(5) =O(1)
            O(2N+1) = O(2N)=O(N)
            O(NN+N+1)= O(NN)
            O(3NNN+1)=O(3NNN)=O(NNN)
   
        算法效率的度量  
          常见时间复杂度类型
          常数阶
          线性阶
          平方阶
          对数阶
          nlogn阶
          立方阶
          指数阶




最坏与最好
在没有特殊说明时,,我们 我们所分析的算法的时
间复杂度都是指最坏时间复杂度。


算法空间复杂度.
  算法的空间复杂度通过计算算法的存储空间来实现
  s(n) =O(f(n));




空间与时间的策略
  多数情况下,算法执行所用的时候更加令人关注.
  如果有毕业,可以过过增加空间复杂度来降低时间复杂性.
  同理,也可以过过增加时间复杂度来降低空间复杂度.
   在实现算法时,
   需要分析具体问题对执行时间和空间的要求..
      






专题二 .线性表.


第一节:线性表的本质.
1. 
  线性表的定义
  a.线性表(List)是0个或多个数据元素的集合.
  b.线性表中的数据元素之间是有顺序的.
  c.线性表的数据元素是有限的.
  d.线性表中的数据元素的类型必须相同.
  
  定义: 线性表是具有相同类型的N(N>0)个数据元素的有限序列.
      (a1,a2,,,,,,an) ai是表项,n 是表长度.
      
   性质:
     a0是线性表的第一个元素,只有一个后继.
     an为线性表的最后一个元素,只有一个前驱.
     除了a0和an外的其它的元素ai, 有前驱后继.
     线性表能够逐项访问和顺序存取.
    
  小结:
    线性表是数据元素的有序并且有限的集合
    线性表中的数据元素必须是类型相同的
    线性表可用于描述队列类型关系的问题.
     一年的12个月构成了一种线性表.
     
     
 第二节,线性表的相关操作.
 
 主要内容.
 1.线性表的操作.
   a. 创建线性表
   b. 销毁线性表
   c.清空线性表
   d.将元素插入线性表
   e.将元素从线性表中删除
   g.获取线性表中的某个元素的位置.
   h.获取线性表的长度.
   
 线性表操作的实现
  线性表在程序中表现为一种特殊的数据类型
  线性表的操作在程序中表现为一组函数
  List
    List * List_Creat();
    void List_Destroy(List * list);
    void List_Clear(List *list);
    int List_Length(List* list);
    ListNode* List_Delete(List* list, int pos);
    ListNode* List_Get(List* list, int pos);
    int List_Insert(List* list, ListNode* node, int pos);
  
  用C语言描述线性表E:\数据结构(国嵌)\lxmcode\TestList
     
 小结:
   线性表在程序中表现为一种特殊的数据类型
   线性表的操作则表现为一组相关的函数.
    问题:线性表的各个函数如何实现?
         有几种线性表的实现方式?
         每种实现方式的优缺点是什么?
         
第三节 线性的顺序存储结构


本节主要内容.
 1.顺序存储结构定义 
   线性表的顺序存储结构,,指的是用一段 指的是用一段
地址连续的存储单元依次存储线性表的
数据元素。
 2.顺序存储结构
 
在C语言中可以用一维数组来实现顺序存储结构
存储空间的起始位置::数组 数组node
线性表的最大容量::数组长度 数组长度MAXSIZE
线性表的当前长度:length

       #define MAXSIZE 20
       typedef struct _tag_List{
        char node[MAXSIZE];
        int length;
       }List;

 3.顺序存储结构的操作
    
   a.获取元素操作.
       判断线性表是否合法
       判断位置是否合法.
       直接通过数组下标的方式获取元素.
        char Get(List * list, int pos){
        char ret = -1;
        //1.判断线性表是否合法
        //.判断位置是否合法
        if( (list !=NULL) && (0 <= pos) && (pos < list->length) )
        {
        //获取元素
        ret = list->node[pos];
        }
       
        return ret;
        }
        
     b. 插入元素算法
判断线性表是否合法
判断插入位置是否合法
把最后一个元素到插入位置的元素后移一个位置
将新元素插入
线性表长度加1

int Insert(List * list ,char c , int pos)
{
//1.判断线性表是否合法
int ret = (list!=NULL);
int i = 0;
//2.判断插入位置是否合法
ret = ret && (list->length +1 <= MAXSIZE);
ret = ret &&(0 <= pos);

if(ret)
{
if(pos >= list->lentgh)
{
pos = list->length;
}
//3.从最后一个元素开始到第pos个位置
//分别将他们都向后移动一个位置
for(i=list->length; i>pos; i--)
{
list->node[i] = list->node[i-1];
}
//4.将新元素插入
list->node[i] = c;

list->length++;
}

return ret;
}

 C 删除元素算法
判断线性表是否合法
判断删除位置是否合法
将元素取出
将删除位置后的元素分别向前移动一个位置
线性表长度减1
char Delete(List *list, int pos)
{
char ret = -1;
int i = 0;
//1.判断线性表是否合法
//2.判断删除位置是否合法
if( (list!=NULL) && (0 <= pos) && (pos < list->length) )
{
   //获取删除元素
   ret = list->node[pos];
for(int i = pos + 1; i <list->length; i++)
        {
           //4.把删除位置pos后的元素分别向前移动一个位置
        list ->node[i-1] = list->node[i];
        }
        //5.长度减1
        list->length--;
}
return ret;
}


创建可复用的线性表:


代码如下:


#include <stdio.h>
#include <malloc.h>
#include "SeqList.h"


typedef unsigned int TSeqListNode;


typedef struct _tag_SeqList
{
    int capacity;
    int length;
    TSeqListNode* node;
} TSeqList;


SeqList* SeqList_Create(int capacity) // O(1)
{
    TSeqList* ret = NULL;
    
    if( capacity >= 0 )
    {
        ret = (TSeqList*)malloc(sizeof(TSeqList) + sizeof(TSeqListNode) * capacity);
    }
    
    if( ret != NULL )
    {
        ret->capacity = capacity;
        ret->length = 0;
        ret->node = (TSeqListNode*)(ret + 1);
    }
    
    return ret;
}


void SeqList_Destroy(SeqList* list) // O(1)
{
    free(list);
}


void SeqList_Clear(SeqList* list) // O(1)
{
    TSeqList* sList = (TSeqList*)list;
    
    if( sList != NULL )
    {
        sList->length = 0;
    }
}


int SeqList_Length(SeqList* list) // O(1)
{
    TSeqList* sList = (TSeqList*)list;
    int ret = -1;
    
    if( sList != NULL )
    {
        ret = sList->length;
    }
    
    return ret;
}


int SeqList_Capacity(SeqList* list) // O(1)
{
    TSeqList* sList = (TSeqList*)list;
    int ret = -1;
    
    if( sList != NULL )
    {
        ret = sList->capacity;
    }
    
    return ret;
}


int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) // O(n) 
{
    TSeqList* sList = (TSeqList*)list;
    int ret = (sList != NULL);
    int i = 0;
    
    ret = ret && (sList->length + 1 <= sList->capacity);
    ret = ret && (0 <= pos);
    
    if( ret )
    {
        if( pos >= sList->length )
        {
            pos = sList->length;
        }
        
        for(i=sList->length; i>pos; i--)
        {
            sList->node[i] = sList->node[i-1];
        }
        
        sList->node[i] = (TSeqListNode)node;
        
        sList->length++;
    }
    
    return ret;
}


SeqListNode* SeqList_Get(SeqList* list, int pos) // O(1) 
{
    TSeqList* sList = (TSeqList*)list;
    SeqListNode* ret = NULL;
    
    if( (sList != NULL) && (0 <= pos) && (pos <= sList->length) )
    {
        ret = (SeqListNode*)(sList->node[pos]);
    }
    
    return ret;
}


SeqListNode* SeqList_Delete(SeqList* list, int pos) // O(n)
{
    TSeqList* sList = (TSeqList*)list;
    SeqListNode* ret = SeqList_Get(list, pos);
    int i = 0;
    
    if( ret != NULL )
    {
        for(i=pos+1; i<sList->length; i++)
        {
            sList->node[i-1] = sList->node[i];
        }
        
        sList->length--;
    }
    
    return ret;
}


#ifndef _SEQLIST_H_
#define _SEQLIST_H_


typedef void SeqList;
typedef void SeqListNode;


SeqList* SeqList_Create(int capacity);


void SeqList_Destroy(SeqList* list);


void SeqList_Clear(SeqList* list);


int SeqList_Length(SeqList* list);


int SeqList_Capacity(SeqList* list);


int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);


SeqListNode* SeqList_Get(SeqList* list, int pos);


SeqListNode* SeqList_Delete(SeqList* list, int pos);


#endif




#include <stdio.h>
#include <stdlib.h>
#include "SeqList.h"


/* run this program using the console pauser or add your own getch, system("pause") or input loop */


int main(int argc, char *argv[]) 
{
    SeqList* list = SeqList_Create(5);
    
    int i = 0;
    int j = 1;
    int k = 2;
    int x = 3;
    int y = 4;
    int z = 5;
    int index = 0;
    
    SeqList_Insert(list, &i, 0);
    SeqList_Insert(list, &j, 0);
    SeqList_Insert(list, &k, 0);
    SeqList_Insert(list, &x, 0);
    SeqList_Insert(list, &y, 0);
    SeqList_Insert(list, &z, 0);
    
    for(index=0; index<SeqList_Length(list); index++)
    {
        int* p = (int*)SeqList_Get(list, index);
        
        printf("%d\n", *p);
    }
    
    printf("\n");
    
    while( SeqList_Length(list) > 0 )
    {
        int* p = (int*)SeqList_Delete(list, 0);
        
        printf("%d\n", *p);
    }
    
    SeqList_Destroy(list);
    
    return 0;
}




小结: 
   优点:
     无需要国线性表中的逻辑关系增加额外的空间.
     可以快速的获取表中合法位置的元素.
    缺点:
      插入和删除操作需要移动大量元素.
      当线性表长度变化输大时难以确定存储空间.


第4小节 线性表的链式存储结构.


1.  问题: 顺序表的思考.
    顺序表的最大问题是插入和删除需要移动大量的元素.如何解决.
   
2.  链式存储结构的定义.
    为了表示每个数据元素与其直接后继元素之间的
逻辑关系,,每个元素除了存储本身的信息外 每个元素除了存储本身的信息外,,还还
需要存储指示其直接后继的信息。

3.  链式存储逻辑结构  

n个结点链接成一个链式线性表的结构叫做链表,
当每个结点中只包含一个指针域时,,叫做单链表 叫做单链表.


4.  链表的基本概念
41表头结点
链表中的第一个结点,,包含指向第一个数据元素的指针以及 包含指向第一个数据元素的指针以及
链表自身的一些信息
42数据结点
   链表中代表数据元素的结点,,包含指向下一个数据元素的指 包含指向下一个数据元素的指
   针和数据元素的信息
43尾结点
   链表中的最后一个数据结点,,其下一元素指针为空 其下一元素指针为空,,表示无 表示无
  后继

5 链式存储结构
51:在C语言中可以用结构体来定义链表中的指针域
52:链表中的表头结点也可以用结构体实现
  
code:
结点指针域定义
 typedef struct _tag_LinkListNode LinkListNode;
 struct _tag_LinkListNode
 {
  LinkListNode * next;
 };
 头结点定义
 typedef struct _tag_LinkList
 {
  LinkListNode header;
  int length;
 }TLinkList;
 
 数据元素定义示例
 struct Value
 {
  LinkListNode header;
  int v;
 }


    53获取第pos个元素操作
判断线性表是否合法
判断位置是否合法
由表头开始通过n ext指针移动pos次后,,当前元素的 当前元素的n ext指
针即指向要获取的元素
LinkListNode * current  = (LinkListNode *) list;
for(i=0; i<pos; i++)
{
current = current->next;
}

ret = current->next;

    54插入元素操作
       插入元素到位置pos的算法
判断线性表是否合法
判断插入位置是否合法
由表头开始通过n ext指针移动pos次后,,当前元素的 当前元素的n ext指
针即指向要插入的位置
   将新元素插入
   线性表长度加1
   LinkListNode * current = (LinkListNode *) list;
   for(i = 0;(i < pos) && (current->netx != NULL); i++)
   {
    current = current->netx;
   }
   node->next = current->next;
   current->netx = node;
   
   sList->length++;



 
55 删除元素操作


删除第pos个元素的算法
判断线性表是否合法
判断插入位置是否合法
获取第pos个元素
将第pos个元素从链表中删除
线性表长度减1




创建可复用单链表
code
#ifndef _LINKLIST_H_
#define _LINKLIST_H_


typedef void LinkList;
typedef struct _tag_LinkListNode LinkListNode;
struct _tag_LinkListNode
{
    LinkListNode* next;
};


LinkList* LinkList_Create();


void LinkList_Destroy(LinkList* list);


void LinkList_Clear(LinkList* list);


int LinkList_Length(LinkList* list);


int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);


LinkListNode* LinkList_Get(LinkList* list, int pos);


LinkListNode* LinkList_Delete(LinkList* list, int pos);


#endif


#include <stdio.h>
#include <malloc.h>
#include "LinkList.h"


typedef struct _tag_LinkList
{
    LinkListNode header;
    int length;
} TLinkList;


LinkList* LinkList_Create() // O(1)
{
    TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));
    
    if( ret != NULL )
    {
        ret->length = 0;
        ret->header.next = NULL;
    }
    
    return ret;
}


void LinkList_Destroy(LinkList* list) // O(1)
{
    free(list);
}


void LinkList_Clear(LinkList* list) // O(1)
{
    TLinkList* sList = (TLinkList*)list;
    
    if( sList != NULL )
    {
        sList->length = 0;
        sList->header.next = NULL;
    }
}


int LinkList_Length(LinkList* list) // O(1)
{
    TLinkList* sList = (TLinkList*)list;
    int ret = -1;
    
    if( sList != NULL )
    {
        ret = sList->length;
    }
    
    return ret;
}


int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) // O(n)

    TLinkList* sList = (TLinkList*)list;
    int ret = (sList != NULL) && (pos >= 0) && (node != NULL);
    int i = 0;
    
    if( ret )
    {
        LinkListNode* current = (LinkListNode*)sList;
        
        for(i=0; (i<pos) && (current->next != NULL); i++)
        {
            current = current->next;
        }
        
        node->next = current->next;
        current->next = node;
        
        sList->length++;
    }
    
    return ret;
}


LinkListNode* LinkList_Get(LinkList* list, int pos) // O(n)
{
    TLinkList* sList = (TLinkList*)list;
    LinkListNode* ret = NULL;
    int i = 0;
    
    if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )
    {
        LinkListNode* current = (LinkListNode*)sList;
        
        for(i=0; i<pos; i++)
        {
            current = current->next;
        }
        
        ret = current->next;
    }
    
    return ret;
}


LinkListNode* LinkList_Delete(LinkList* list, int pos) // O(n)
{
    TLinkList* sList = (TLinkList*)list;
    LinkListNode* ret = NULL;
    int i = 0;
    
    if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )
    {
        LinkListNode* current = (LinkListNode*)sList;
        
        for(i=0; i<pos; i++)
        {
            current = current->next;
        }
        
        ret = current->next;
        current->next = ret->next;
        
        sList->length--;
    }
    
    return ret;
}


#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"


/* run this program using the console pauser or add your own getch, system("pause") or input loop */


struct Value
{
    LinkListNode header;
    int v;
};


int main(int argc, char *argv[]) 
{
    int i = 0;
    LinkList* list = LinkList_Create();
    
    struct Value v1;
    struct Value v2;
    struct Value v3;
    struct Value v4;
    struct Value v5;
    
    v1.v = 1;
    v2.v = 2;
    v3.v = 3;
    v4.v = 4;
    v5.v = 5;
    
    LinkList_Insert(list, (LinkListNode*)&v1, LinkList_Length(list));
    LinkList_Insert(list, (LinkListNode*)&v2, LinkList_Length(list));
    LinkList_Insert(list, (LinkListNode*)&v3, LinkList_Length(list));
    LinkList_Insert(list, (LinkListNode*)&v4, LinkList_Length(list));
    LinkList_Insert(list, (LinkListNode*)&v5, LinkList_Length(list));
    
    for(i=0; i<LinkList_Length(list); i++)
    {
        struct Value* pv = (struct Value*)LinkList_Get(list, i);
        
        printf("%d\n", pv->v);
    }
    
    while( LinkList_Length(list) > 0 )
    {
        struct Value* pv = (struct Value*)LinkList_Delete(list, 0);
        
        printf("%d\n", pv->v);
    }
    
    LinkList_Destroy(list);
    while(1);
    
    return 0;
}


优点:
无需一次性定制链表的容量
插入和删除操作无需移动数据元素
缺点:
数据元素必须保存后继元素的位置信息
获取指定数据的元素操作需要顺序访问之前的元素


顺序表的实现中为什么保存的是具体数据元
素的地址??而保存的地址存放在 而保存的地址存放在unsigned 
int中中,,,而不是具体的指针类型中 而不是具体的指针类型中??为什么不 为什么不
是void*呢呢?




以下关于链式存储结构的叙述中正确的是
 A. 链式存储结构不是顺序存取结构
 B. 逻辑上相邻的结点物理上必相邻
 C. 可以通过计算直接确定第 i个元素 个元素
 D. 插入和删除操作方便,,不必移动其它结点


在单链表的实现和应用中,,还有一种无表头 还有一种无表头
结点的单链表。。根据我们列出的操作 根据我们列出的操作,,编程 编程
实现这种无表头结点的单链表,,并对比表头 并对比表头
实现方式和无表头实现方式哪种更好。


为我们实现的顺序表和单链表添加一个反转操
作作。。。这个操作使得链表中的次序反转 这个操作使得链表中的次序反转,,即第一 即第一
个元素变为最后一个元素,,第二个元素变为倒 第二个元素变为倒
数第二个元素。。。如如:::abcd abcd abcd反转的结果为 反转的结果为
dcba dcba。 。
要求时间复杂度达到O(n)。
SeqList_Reverse(SeqList* list);
LinkList_Reverse(LinkList* list);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!关于学习数据结构的C语言笔记,我可以给你一些基本的指导和概念。数据结构是计算机科学中非常重要的一门课程,它涉及存储和组织数据的方法。C语言是一种常用的编程语言,很适合用于实现各种数据结构。 下面是一些数据结构的基本概念,你可以在学习笔记中包含它们: 1. 数组(Array):一种线性数据结构,可以存储相同类型的元素。在C语言中,数组是通过索引访问的。 2. 链表(Linked List):也是一种线性数据结构,但不需要连续的内存空间。链表由节点组成,每个节点包含数据和指向下一个节点的指针。 3. 栈(Stack):一种后进先出(LIFO)的数据结构,类似于装满物品的箱子。在C语言中,可以使用数组或链表来实现栈。 4. 队列(Queue):一种先进先出(FIFO)的数据结构,类似于排队等候的队伍。同样可以使用数组或链表来实现队列。 5. 树(Tree):一种非线性数据结构,由节点和边组成。每个节点可以有多个子节点。二叉树是一种特殊的树结构,每个节点最多有两个子节点。 6. 图(Graph):另一种非线性数据结构,由节点和边组成。图可以用来表示各种实际问题,如社交网络和地图。 这只是数据结构中的一些基本概念,还有其他更高级的数据结构,如堆、哈希表和二叉搜索树等。在学习笔记中,你可以介绍每个数据结构的定义、操作以及适合使用它们的场景。 希望这些信息对你有所帮助!如果你有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值