数据结构c语言版 严蔚敏 课本源码

第2章  线性表 - 单链表顺序存储结构

——《数据结构》-严蔚敏.吴伟民版



概述

       数据结构的学习当然要从线性表学起,而线性表里首先需要学习单链表,这里从单链表最简单的顺序存储结构(本质就是可变数组存储)开始。

解析

       单链表强调元素在逻辑上紧密相邻,所以首先想到用数组存储。但是普通数组有着无法克服的容量限制,在不知道输入有多少的情况下,很难确定出一个合适的容量。对此,一个较好的解决方案就是使用动态数组。首先用malloc申请一块拥有指定初始容量的内存,这块内存用作存储单链表元素,当录入的内容不断增加,以至于超出了初始容量时,就用calloc扩展内存容量,这样就做到了既不浪费内存,又可以让单链表容量随输入的增加而自适应大小。

       单链表顺序存储结构如下图:

可能涉及到的语法难点

       刚接触数据结构的同学,单链表顺序存储结构可能会是其面对的第一个坎。这里涉及到了结构体动态数组结构指针,甚至还有函数变量(函数做参数,本质是函数指针),所以需要有相对扎实的语言语法基础。当然,这也并不是说一定得掌握了高级语法才能开始学习数据结构,可以先将语言学到入门(入门意味着学会了提问),再边学数据结构边巩固语法。一定要亲自动手写一写,否则,肯定学不好。

概述

       数据结构的学习当然要从线性表学起,而线性表里首先需要学习单链表,这里从单链表最简单的顺序存储结构(本质就是可变数组存储)开始。

解析

       单链表强调元素在逻辑上紧密相邻,所以首先想到用数组存储。但是普通数组有着无法克服的容量限制,在不知道输入有多少的情况下,很难确定出一个合适的容量。对此,一个较好的解决方案就是使用动态数组。首先用malloc申请一块拥有指定初始容量的内存,这块内存用作存储单链表元素,当录入的内容不断增加,以至于超出了初始容量时,就用calloc扩展内存容量,这样就做到了既不浪费内存,又可以让单链表容量随输入的增加而自适应大小。

       单链表顺序存储结构如下图:

可能涉及到的语法难点

       刚接触数据结构的同学,单链表顺序存储结构可能会是其面对的第一个坎。这里涉及到了结构体动态数组结构指针,甚至还有函数变量(函数做参数,本质是函数指针),所以需要有相对扎实的语言语法基础。当然,这也并不是说一定得掌握了高级语法才能开始学习数据结构,可以先将语言学到入门(入门意味着学会了提问),再边学数据结构边巩固语法。一定要亲自动手写一写,否则,肯定学不好。

stdlib 是c标准库  typedef 是起名字 

#include"stdio.h"
#include"stdlib.h"  
#define TRUE 1 
#define  ERROR 0
typedef struct 
{
  int * elem; //储存空间基地址     
  int length; // 记录当前链表长度  
  int listsize; //链表规模
} SqList;
int InitList(SqList *L)
{
(*L).elem =(int*)malloc( 100*sizeof(int) ); //返回NULL 
if (!(*L).elem) 
     {
 printf("顺序表初始化失败");
  exit(-2); //内存分配失败 
}
(*L).length=1;
(*L).listsize =100;  
    return 1;
}


void Clear_Sq(SqList *L)
{
(*L).length =0;

void Destroy(SqList*L)
{
free((*L).elem);
(*L).elem =NULL;

(*L).length =0;
}


int ListEmpty_Sq(SqList L)  //值拷贝  


{
return L.length ==0 ?1:0; 

}


int ListLength_Sq(SqList L)
{
    return L.length ;
    
 } 
 
 int  GetEle_Sq(SqList L,int i,int *e)
{
   if (i<1||i>L.length)
   return 0;
       *e =L.elem[i-1];
       return 1;
 }  
/*
往顺序表中插入值。数字下标从零开始。 


*/ 
int ListInsert_Sq(SqList *L ,int i, int e) 
{  
   int * newbase;
   int *p,*q;
   if (i<1||i>(*L).length)
    return 0;
   if((*L).length >=(*L).listsize)
    {
    newbase = ( int *)realloc ((*L).elem,((*L).listsize+10)*sizeof(int));
                                // 第一个参数是线性表节点地址 第二个参数是在开辟多大的内存 。
(*L) .elem = newbase;
(*L).listsize+=10;
}
q =&(*L).elem[i-1];  
for (p=&(*L).elem[(*L).length-1];p>=q;--p) //元素储存位置挨个减一 ,插入第一个数不进入这个循环。 
    {
    *(p+1)=*p; 
}
*q=e;
(*L).length++; 
   return 1;

int LocateElem_Sq(SqList L,int e ) 
{
   int i=1;
   while(i<L.length && L.elem [i-1]!=e)
    {
i++;
}
  if (i<L.length )
   {  return i;
  }
return 0;
}
  
int ListDelete_Sq(SqList *L,int i,int *e)
{
int j;
int *p,*q ;  
 if (i<1||i>(*L).length )
  return 0;
p=&(*L).elem [i-1];
*e=*p; 
q=(*L).elem +(*L).length -1;//elem[length-1]
for  (++p;p<=q;++p)
{
*(p-1)= *p;
 
}
(*L).length--;
return 1;


/* 线性表遍历 从0到legnth-1; 
*/
int ListTraverse_Sq(SqList L)
{
 int i;
 for (i=0;i<L.length-1 ;i++)
     printf(" 打表 %d ",L.elem [i]);

}
int main()
{
SqList L;
int  e;
int i; 
if(InitList(&L)==1)
 {
  printf("顺序表初始化成功\n"); 
 } 
printf("当前线性表长度%d\n",L.length-1); 
  //   L.length=1; 
//ListTraverse_Sq(L);
for(i=1;i<10;i++)
ListInsert_Sq(&L,i, 2*i); //插入一个元素  
printf("当前线性表长度%d\n",L.length-1); 
printf("4的定 =% d\n",LocateElem_Sq(L,4));
ListTraverse_Sq(L);
ListDelete_Sq(&L,2,&e);
printf("删除的第二个元素是%d\n",e); 
ListTraverse_Sq(L);
return 0;

}

用插入一个值给链表复制时候如果,链表长度小于1,会出现ele[-1],这个错误。







概述

       数据结构的学习当然要从线性表学起,而线性表里首先需要学习单链表,这里从单链表最简单的顺序存储结构(本质就是可变数组存储)开始。

解析

       单链表强调元素在逻辑上紧密相邻,所以首先想到用数组存储。但是普通数组有着无法克服的容量限制,在不知道输入有多少的情况下,很难确定出一个合适的容量。对此,一个较好的解决方案就是使用动态数组。首先用malloc申请一块拥有指定初始容量的内存,这块内存用作存储单链表元素,当录入的内容不断增加,以至于超出了初始容量时,就用calloc扩展内存容量,这样就做到了既不浪费内存,又可以让单链表容量随输入的增加而自适应大小。

       单链表顺序存储结构如下图:

可能涉及到的语法难点

       刚接触数据结构的同学,单链表顺序存储结构可能会是其面对的第一个坎。这里涉及到了结构体动态数组结构指针,甚至还有函数变量(函数做参数,本质是函数指针),所以需要有相对扎实的语言语法基础。当然,这也并不是说一定得掌握了高级语法才能开始学习数据结构,可以先将语言学到入门(入门意味着学会了提问),再边学数据结构边巩固语法。一定要亲自动手写一写,否则,肯定学不好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章