數據結構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擴展內存容量,這樣就做到了既不浪費內存,又可以讓單鏈表容量隨輸入的增加而自適應大小。

       單鏈表順序存儲結構如下圖:

可能涉及到的語法難點

       剛接觸數據結構的同學,單鏈表順序存儲結構可能會是其面對的第一個坎。這裏涉及到了結構體動態數組結構指針,甚至還有函數變量(函數做參數,本質是函數指針),所以需要有相對紮實的語言語法基礎。當然,這也並不是說一定得掌握了高級語法才能開始學習數據結構,可以先將語言學到入門(入門意味着學會了提問),再邊學數據結構邊鞏固語法。一定要親自動手寫一寫,否則,肯定學不好。

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