資料結構學習筆記(1.大O表示法和順序表)
阿新 • • 發佈:2019-02-19
最近在看國嵌唐老師的資料結構視訊,覺得還不錯,所以就把筆記記錄下來
本節知識點:
1.資料之間的邏輯結構: 集合結構:資料元素之間沒有特別的關係,僅同屬相同集合 線性結構:資料元素之間是一對一的關係 樹形結構:資料元素之間存在一對多的層次關係 圖形結構:資料元素之間是多對多的關係2.資料之間的物理結構 順序儲存結構:將資料儲存在地址連續的儲存單元裡 鏈式儲存結構:將資料儲存在任意的儲存單元裡,通過儲存地址的方式找到相關的資料元素3.資料結構是相互之間存在一種或多種特定關係的資料元素的集合4.程式 = 資料結構 + 演算法5.大O表示法:演算法效率嚴重依賴於運算元量,首先關注運算元的最高次項本節程式碼:
1.本節的程式碼是一個可以適合各種型別的順序表,之所以能夠適合各種型別,是因為它在順序表中儲存的是元素的地址(其實就是一個指標陣列)。2.程式碼中的描述順序表的結構體中的元素介紹:length是順序表中有元素的個數、capacity是順序表的容量、node是順序表的頭地址(也是這個指標陣列的頭地址)、還有一個就是pos,pos是在刪除和插入的時候使用的一個引數,它代表的是插入到順序表位置的下標(陣列的下標 是從0開始的 這個很要注意)。順序表中有length個元素 下標是從0到length-1的。要注意的是 操作順序表不同功能函式的pos的允許範圍是不一樣的。/************************************************************************************
檔名:Seqlist.c
標頭檔案:Seqlist.h
時間: 2013/08/05
作者: Hao
功能:可以複用 帶有增 刪 改 查 功能的順序表
難點:1.順序表中存放的都是 各種資料的地址
2.void *是用來隔離封裝用的 保證順序表結構體只能被特定的函式改變
************************************************************************************/
#include <stdio.h>
#include <malloc.h>
#include "Seqlist.h"
typedef unsigned int TSeqListNode;//這個順序表中存放的是 各種資料的地址 所以用unsigned int
typedef struct str_SeqList
{
int length;//順序已用的長度
int capacity;//順序表的總容量
TSeqListNode* node;//這個指標是用來在順序表中游走讀取資料用的
}TSeqList; //定義描述順序表的結構體
/************************************************************************************
函式名: Creat_SeqList
函式功能: 建立一個容量為capacity的順序表
引數: int capacity 建立順序表中成員的個數 即順序表容量
返回值: void* ret 如果返回NULL 說明建立順序表失敗
如果返回ret 說明建立順序表成功 且ret為描述順序表的結構體
************************************************************************************/
SeqList* Creat_SeqList(int capacity)
{
TSeqList* ret = NULL;
/*進入函式 第一點是先判斷傳人蔘數的合法性*/
if(capacity >= 0)
{
/*給順序表開闢空間*/
ret=(TSeqList* )malloc(sizeof(TSeqList)+sizeof(TSeqListNode)*capacity);
if(NULL!=ret)//空間開闢成功 給描述順序表的結構體 賦值
{
ret->capacity=capacity;
ret->length=0;
ret->node=(TSeqListNode* )(ret+1);//把真正順序表的地址賦給 node
}
}
else
{
ret = NULL;
}
return (SeqList*)(ret);
}
/************************************************************************************
函式名: Destroy_SeqList
函式功能: 銷燬順序表 free開闢的記憶體
引數: void* list 描述順序表結構體指標
返回值: void
************************************************************************************/
void Destroy_SeqList(SeqList* list)
{
free(list);
}
/************************************************************************************
函式名: Get_Seqlist_Length
函式功能:獲得順序表 現在的大小
函式引數:void* list 描述順序表結構體指標
函式返回值:int ret 成功返回length
失敗返回-1
************************************************************************************/
int Get_Seqlist_Length(SeqList* list)
{
int ret;
TSeqList *Tlist=(TSeqList* )list;
/*函式引數合法性檢測*/
if(NULL != Tlist)
{
ret=Tlist->length;
}
else
ret=-1;
return ret;
}
/************************************************************************************
函式名: Get_Seqlist_Capacity
函式功能:獲得順序表 的容量
函式引數:void* list 描述順序表結構體指標
函式返回值:int ret 成功返回capacity
失敗返回-1
************************************************************************************/
int Get_Seqlist_Capacity(SeqList* list)
{
int ret;
TSeqList *Tlist=(TSeqList* )list;
/*函式引數合法性檢測*/
if(NULL != Tlist)
{
ret = Tlist->capacity;
}
else
ret=-1;
return ret;
}
/************************************************************************************
函式名: Clean_Seqlist_Length
函式功能:清空順序表 其實就是給length=0;
函式引數:void* list 描述順序表結構體指標
函式返回值:int ret 成功返回0
失敗返回-1
************************************************************************************/
int Clean_Seqlist_Length(SeqList* list)
{
int ret;
TSeqList *Tlist=(TSeqList* )list;
/*函式引數合法性檢測*/
if(NULL != Tlist)
{
Tlist->length=0;
ret=0;
}
else
ret=-1;
return ret;
}
/************************************************************************************
函式名: Seqlist_Add
函式功能:順序表中有length個數據 在下標為pos的位置上 插入資料node 所以pos是從0開始的 length是從1開始的
引數: SeqList* list描述順序表的結構體地址 SeqListNode* node插入順序表的資料的地址
int pos插入順序表的位置 pos的範圍是從0(此時在順序表頭部插入)開始 到length(此時就是在順序尾部插入)
總共是length+1個位置
返回值 : 返回1 說明插入資料成功 返回0 說明插入資料失敗
************************************************************************************/
int Seqlist_Add(SeqList* list, SeqListNode* node ,int pos)
{
/*引數合法性檢測*/
TSeqList *Tlist=(TSeqList* )list;
int ret = (NULL != list);
int i;
ret=ret && (pos >= 0);
ret=ret && (Tlist->length+1 <= Tlist->capacity); //判斷再插入一個數據的時候 length有沒有超過 capacity
if(1 == ret)
{
if(pos >= Tlist->length)//如果插入的位置pos比 length大的話 預設把length+1賦值給pos
{
pos = Tlist->length;
}
for(i=Tlist->length;i>pos;i--)
{
Tlist->node[i]=Tlist->node[i-1];
}
Tlist->node[i]=(TSeqListNode)node; //把要插入的地址強制型別轉換成 unsigned int*
Tlist->length++;
}
return ret;//返回1 說明插入資料成功 返回0 說明插入資料失敗
}
/************************************************************************************
函式名: Get_Node
函式功能:找到順序表中下標為pos的值
引數: pos插入順序表的下標 pos的範圍是從0到length-1
SeqList* list描述順序表的結構體地址
返回值: void* ret 找到pos為下標的那個值
如果成功返回pos為下標的那個值 如果失敗 返回NULL
************************************************************************************/
SeqListNode* Get_Node(SeqList* list, int pos)
{
TSeqList* Tlist=(TSeqList* )list;
SeqListNode* ret=NULL;
if( (NULL!=Tlist) && (pos>=0) && (pos<Tlist->length) )
{
ret=(SeqListNode* )Tlist->node[pos]; //強制型別轉換成void*
}
return ret;
}
/************************************************************************************
函式名: Del_Node
函式功能:找到順序表中下標為pos的值 並且刪除它
引數: 刪除pos為下標的值 pos的範圍是從0到length-1
SeqList* list描述順序表的結構體地址
返回值: void* ret
如果成功返回pos為下標的那個值 如果失敗 返回NULL
************************************************************************************/
SeqListNode* Del_Node(SeqList* list, int pos)
{
TSeqList* Tlist=(TSeqList* )list;
SeqListNode* ret=NULL;
int i;
if( (NULL!=Tlist) && (pos>=0) && (pos<Tlist->length) )
{
ret=(SeqListNode* )Tlist->node[pos];
for(i=pos+1; i<Tlist->length; i++)
{
Tlist->node[i-1]=Tlist->node[i];
}
Tlist->length--;
}
return ret;
}
Seqlist.h:
#ifndef __Seqlist__
#define __Seqlist__
typedef void SeqList; //是用來封裝 使順序表結構體 不被外界改變 只可被Seqlist.c檔案中的函式改變
//因為 這些函式 對外的介面 都是void*
typedef void SeqListNode;//SeqList 是用來表示 順序表的 SeqListNode是用來表示順序表 中變數的
SeqList* Creat_SeqList(int capacity);
void Destroy_SeqList(SeqList* list);
int Get_Seqlist_Length(SeqList* list);
int Get_Seqlist_Capacity(SeqList* list);
int Clean_Seqlist_Length(SeqList* list);
int Seqlist_Add(SeqList* list, SeqListNode* node ,int pos);
SeqListNode* Get_Node(SeqList* list, int pos);
SeqListNode* Del_Node(SeqList* list, int pos);
#endif
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "Seqlist.h"
int main(int argc, char *argv[])
{
SeqList* My_SeqList = NULL;
int a = 10;
int b = 5;
int c = 3;
int d = 6;
int e = 1;
int *p = NULL;
int i = 0;
My_SeqList = Creat_SeqList(5);
if( NULL != My_SeqList )
{
Seqlist_Add(My_SeqList, &a ,0);
Seqlist_Add(My_SeqList, &b ,0);
Seqlist_Add(My_SeqList, &c ,0);
Seqlist_Add(My_SeqList, &d ,0);
Seqlist_Add(My_SeqList, &e ,0);
for(i=0; i<Get_Seqlist_Length(My_SeqList); i++)
{
p=Get_Node(My_SeqList, i);
printf("%d\n",*p);
}
Del_Node(My_SeqList, 3);
for(i=0; i<Get_Seqlist_Length(My_SeqList); i++)
{
p=Get_Node(My_SeqList, i);
printf("%d\n",*p);
}
}
Clean_Seqlist_Length(My_SeqList);
Destroy_SeqList(My_SeqList);
return 0;
}
仔細觀察下面錯誤程式碼,test_main.c:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "Seqlist.h"
typedef struct student
{
int student_num;
char name[30];
char sex[20];
int age;
}str;
int main()
{
str* str1;
SeqList* slist=NULL;
int i=0;
int age=0;
slist=Creat_SeqList(50);
if(NULL == slist)
{
printf("malloc error!!!\n");
return -1;
}
for(i=0; i<3; i++)
{
put_student(slist, str1);
}
printf("輸入你要刪除的年齡:\n");
scanf("%d",&age);
printf("\n");
find_student(slist, str1, age);
get_student(slist, str1);
destroy_student(slist, str1);
Clean_Seqlist_Length(slist);
Destroy_SeqList(slist);
return 0;
}
int put_student(SeqList* slist, str* str1)
{
int num;
int ret=(NULL != str1);
if(1 == ret)
{
ret=ret && Seqlist_Add(slist, (str* )malloc(sizeof(str)*1) ,50);
num = Get_Seqlist_Length(slist);
str1 = (str* )Get_Node(slist, num-1);
printf("請輸入學生學號:\n");
scanf("%d",&str1->student_num);
printf("請輸入學生姓名:\n");
scanf("%s",str1->name);
printf("請輸入學生性別:\n");
scanf("%s",str1->sex);
printf("請輸入學生年齡:\n");
scanf("%d",&str1->age);
printf("\n");
}
else
{
ret = 0;
}
return ret;
}
int get_student(SeqList* slist, str* str1)
{
int ret=(NULL != str1);
int i=0;
if(1 == ret)
{
for(i=0; i<Get_Seqlist_Length(slist); i++)
{
str1 = (str*)Get_Node(slist, i);
printf("學生學號:%d\n",str1->student_num);
printf("學生姓名:%s\n",str1->name);
printf("學生性別:%s\n",str1->sex);
printf("學生年齡:%d\n",str1->age);
}
}
else
{
ret = 0;
}
return ret;
}
int destroy_student(SeqList* slist, str* str1)
{
int ret=(NULL != str1);
int i=0;
if(1 == ret)
{
for(i=0; i<Get_Seqlist_Length(slist); i++)
{
str1 = (str*)Get_Node(slist, i);
free(str1);
}
}
else
{
ret = 0;
}
return ret;
}
int find_student(SeqList* slist, str* str1, int age)
{
int ret=(NULL != str1);
int i=0;
int num=0;
if(1 == ret)
{
num=Get_Seqlist_Length(slist);
for(i=0; i<num; i++)
{
str1 = (str*)Get_Node(slist, i);
if(str1->age == age)
{
Del_Node(slist, i);
num=Get_Seqlist_Length(slist);
i--;
}
}
}
else
{
ret = 0;
}
return ret;
}