================================================================
數據結構
2013.08.08 記
================================================================
今天主要對數據結構進行回顧,這些結構平時開發時也有些在使用,但
並沒做系統的學習和歸納,藉此機會惡補一下這門功底。
方式:
1.由最熟悉的線性表開始逐漸至樹,圖形結構進行學習
2.記錄完整學習筆記
3.對於每種數據結構,進行demo的編寫,包括初始化,加入,刪除,回收等操作
4.重點還是鏈表,隊列及二叉樹方面
概述
----------
存儲方式:順序和非順序(鏈式)
邏輯結構:線性和非線性
線性:線性表,棧,隊列
非線性:樹形結構和圖形結構
運算:初始化,增加,刪除,查找,排序,修改等
還是以最熟悉的線性表切入
線性表:分爲靜態和動態,在C語言中,這也是最常見的數據結構
典型的靜態線性表,是一個結構體數組,而且必須預先分配一個鏈表池,對應存儲上
是一塊連續的存儲區,數據成員一般包括數據域和遊標(數組下標),如下
typedef struct {
int data; //data 數據域
int cursor; //遊標
}STATIC_LIST, * STATIC_LIST_PTR;
對結構題數據的尋址就需要用cursor下標來偏移得到,並且在使用前必須分配內存
STATIC_LIST node_t[MAX]; //定義一個結構體數組,最大容量16個
這種用數組順序存儲在C語言中很少使用,有了指針的C實現動態鏈表更加方便。
這裏寫了一個demo簡單實現順序線性表,包括初始化,加入,刪除節點操作。
參考c_list.c
我在鏈表節點之上,使用last變量來記錄當前表的末尾。
加入節點:
在1 <= i <= n之間加入一個節點時,都需要將第n到I向後移一個節點位置。並且
last < LIST_MAX(節點未滿)時,才允許加入節點,並且只能加在 1 <= n <= last+1之間
最後last++
C代碼實現參考insert_list()函數
刪除節點:
在1 <= i <= n之間刪除一個節點時,需要將第i+1至n向前移一個節點位置,並且
last >= 1(節點未空)時,才允許刪除節點,並且只能刪除1 <= n <= last之間的節點
最後last--
C代碼實現參考delete_list()函數
到此,順序線性表的使用基本清楚,但感覺不實用,並且加入和刪除都需移動大量數據塊,
而優點在於能快速隨機的存取節點。
下面還是將重點將放在動態鏈表(單向,單向循環,雙向循環)鞏固上
代碼:
/*
* Author: xz.wang E-mail:
[email protected]
* Last modified: 2013-08-09 00:24
* Filename: c_list.c
* Description:
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 16
typedef struct {
int data;
int cursor;
}STATIC_LIST, * STATIC_LIST_PTR;
typedef struct {
STATIC_LIST_PTR list;
int last;
}SQLIST, * SQLIST_PTR;
/**
* @brief init_list
*
* @param list
* @param value
* @param len
*
* @return
*/
static int init_list(SQLIST *list, int *value, int len)
{
int i;
if (!list || !value)
return -1;
for (i = 0; i < MAX; i++) {
list->list[i].cursor = i + 1;
if (i < len)
list->list[i].data = value[i];
else
list->list[i].data = 0;
}
/* Indicate last node */
list->last = len;
return 0;
}
/**
* @brief insert_list
*
* @param list
* @param i
* @param value
*
* @return
*/
static int insert_list(SQLIST *list, int i, int value)
{
int j;
if (!list)
return -1;
if (i < 1 || i > list->last + 1) {/* invalid */
fprintf(stderr, "New node invalid\n");
return -1;
}
if (list->last >= MAX) {
fprintf(stderr, "New node overflow\n");
return -1; /* overflow */
}
for (j = list->last; j >= i; j--)
list->list[j].data = list->list[j-1].data;
list->list[j].data = value;
list->last += 1;
return 0;
}
/**
* @brief delete_list
*
* @param list
* @param i
*
* @return
*/
static int delete_list(SQLIST_PTR list, int i)
{
int j;
if (!list)
return -1;
if (i < 1 || i > list->last) {
fprintf(stderr, "Delete node invalid\n");
return -1;
}
for (j = i-1; j < list->last; j++)
list->list[j].data = list->list[j+1].data;
list->last -= 1;
return 0;
}
/**
* @brief print_list
*
* @param list
*/
static void print_list(SQLIST *list)
{
int i;
/* output cursor value */
for (i = 0; i < MAX; i++)
fprintf(stderr, "node[%d]:data=%d, cursor=%d\n",
i+1, list->list[i].data, list->list[i].cursor);
fprintf(stderr, "the last node:%d\n", list->last);
}
/*------------------------- Main -------------------------*/
int main(int argc, char *argv[])
{
int ret;
STATIC_LIST node_t[MAX];
SQLIST sqlist;
int value[] = {11,22,33,44,55,66,77};
int len, pos, dat;
/* Initilize static list struct */
memset(node_t, 0, sizeof(STATIC_LIST));
sqlist.list = node_t;
sqlist.last = 0;
len = sizeof(value)/sizeof(value[0]);
ret = init_list(&sqlist, value, len);
if (ret < 0) {
fprintf(stderr, "Initialze list table failed\n");
exit(0);
}
print_list(&sqlist);
/* Insert Test */
fprintf(stderr, "please insert node:");
scanf("%d", &pos);
fprintf(stderr, "please input new value:");
scanf("%d", &dat);
ret = insert_list(&sqlist, pos, dat);
if (ret < 0)
exit(0);
print_list(&sqlist);
/* Delete Test */
fprintf(stderr, "please delete node:");
scanf("%d", &pos);
ret = delete_list(&sqlist, pos);
if (ret < 0)
exit(0);
print_list(&sqlist);
return 0;
}