Chinaunix首页 | 论坛 | 博客
  • 博客访问: 36457
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 230
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-13 00:47
文章分类

全部博文(19)

文章存档

2014年(6)

2013年(13)

我的朋友

分类: C/C++

2013-12-10 16:32:50

线性表:
        线性表是最基本、最简单、也是最常用的一种。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。

特征:
线性结构的基本特征为:
1.集合中必存在唯一的一个“第一元素”;
2.集合中必存在唯一的一个 “最后元素” ;
3.除最后一个元素之外,均有 唯一的后继(后件);
4.除第一个元素之外,均有 唯一的前驱(前件)。
由n(n≥0)个数据元素(结点)a1,a2,…,an组成的有限序列。
数据元素的个数n定义为表的长度。
当n=0时称为空表。
常常将非空的线性表(n>0)记作:
(a1,a2,…an)
数据元素ai(1≦i≦n)只是一个抽象的符号,其具体含义在不同的情况下可以不同。

结构特点
线性表具有如下的结构特点:
1.均匀性:虽然不同数据表的数据元素可以是各种各样的,但对于同一线性表的各数据元素必定具有相同的数据类型和长度。
2.有序性:各数据元素在线性表中的位置只取决于它们的序号,数据元素之前的相对位置是线性的,即存在唯一的“第一个“和“最后一个”的数据元素,除了第一个和最后一个外,其它元素前面均只有一个数据元素直接前驱和后面均只有一个数据元素(直接后继)。
在实现线性表数据元素的存储方面,一般可用顺序存储结构和链式存储结构两种方法。链式存储结构将在本网站线性链表中介绍,本章主要介绍用数组实现线性表数据元素的顺序存储及其应用。另外栈、队列和串也是线性表的特殊情况,又称为受限的线性结构。

//头文件SeqList.h

点击(此处)折叠或打开

  1. #ifndef _SEQLIST_H_
  2. #define _SEQLIST_H_

  3. typedef void SeqList;              
  4. typedef void SeqListNode;

  5. SeqList* SeqList_Create(int capacity);

  6. void SeqList_Destroy(SeqList* list);

  7. void SeqList_Clear(SeqList* list);

  8. int SeqList_Length(SeqList* list);

  9. int SeqList_Capacity(SeqList* list);

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

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

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

  13. #endif
//C源文件SeqList.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "SeqList.h"

  4. typedef unsigned int TSeqListNode;

  5. typedef struct _tag_SeqList
  6. {
  7.     int capacity;
  8.     int length;
  9.     TSeqListNode* node;
  10. } TSeqList;

  11. SeqList* SeqList_Create(int capacity)
  12. {
  13.     TSeqList* ret = NULL;
  14.     if(capacity >= 0) //分配堆空间
  15.     {
  16.         ret = (TSeqList*)malloc(sizeof(TSeqList) + sizeof(TSeqListNode) * capacity);
  17.     }

  18.     if( ret != NULL ) //初始化结构体
  19.     {
  20.         ret->capacity = capacity;
  21.         ret->length = 0;
  22.         ret->node = (TSeqListNode*)(ret + 1);
  23.     }

  24.     return ret;
  25. }

  26. void SeqList_Destroy(SeqList* list)
  27. {
  28.     free(list);
  29. }


  30. void SeqList_Clear(SeqList* list)
  31. {
  32.     TSeqList* slist = (TSeqList*)list;
  33.     if(slist != NULL)
  34.     {
  35.         slist->length = 0;    
  36.     }
  37. }


  38. int SeqList_Length(SeqList* list)
  39. {
  40.     TSeqList* slist = (TSeqList*)list;
  41.     int ret = -1;
  42.     if(slist != NULL)
  43.     {
  44.         ret = slist->length;    
  45.     }
  46.     return ret;
  47. }

  48. int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
  49. {
  50.     TSeqList* slist = (TSeqList*)list;
  51.     int ret;
  52.     int i = 0;
  53.     
  54.     //检查slist是否合法
  55.     //检查插入元素之后,长度是否超过最大容量
  56.     //检查插入位置是否合法
  57.     ret = ret && (slist != NULL);
  58.     ret = ret && (slist->length + 1 <= slist->capacity);
  59.     ret = ret && (0 <= pos);
  60.     
  61.     //如果插入位置不合法,则使其合法
  62.     if(pos >= slist->length)
  63.     {
  64.         pos = slist->length;
  65.     }
  66.     
  67.     
  68.     //先向后移动元素,再插入元素到相应位置
  69.     if(ret)
  70.     {
  71.         for(i = slist->length; i > pos; i--)
  72.         {
  73.             slist->node[i] = slist->node[i-1];    
  74.         }
  75.         slist->node[i] = (TSeqListNode)node;
  76.         slist->length++;    
  77.     }
  78.     return ret;
  79. }


  80. SeqListNode* SeqList_Get(SeqList* list, int pos)
  81. {
  82.     TSeqList* slist = (TSeqList*)list;
  83.     TSeqListNode* ret = NULL;
  84.     
  85.     
  86.     if((slist != NULL) && (0 <= pos) && ( pos <= slist->length))
  87.     {
  88.         ret = (TSeqListNode*)(slist->node[pos]);    
  89.     }
  90.     return ret;    
  91. }

  92. SeqListNode* SeqList_Delete(SeqList* list, int pos)
  93. {
  94.     TSeqList* slist = (TSeqList*)list;
  95.     TSeqListNode* ret = SeqList_Get(slist, pos);
  96.     
  97.     int i = 0;
  98.     
  99.     if(slist != NULL)
  100.     {
  101.         for(i=pos+1; i<slist->length; i++)
  102.         {
  103.             slist->node[i-1] = slist->node[i];    
  104.         }
  105.         slist->length--;    
  106.     }
  107.     return ret;    
  108. }
//测试文件main.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "SeqList.h"

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

  5. int main(int argc, char *argv[])
  6. {
  7.     SeqList* list = SeqList_Create(6);
  8.     
  9.     int index = 0;
  10.     int *p = NULL;
  11.     
  12.     int i = 0;
  13.     int j = 1;
  14.     int k = 2;
  15.     int x = 3;
  16.     int y = 4;
  17.     int z = 5;
  18.     
  19.     SeqList_Insert(list, &i, 0);
  20.     SeqList_Insert(list, &j, 0);
  21.     SeqList_Insert(list, &k, 0);
  22.     SeqList_Insert(list, &x, 0);
  23.     SeqList_Insert(list, &y, 0);
  24.     SeqList_Insert(list, &z, 0);
  25.     
  26.     for(index = 0; index < SeqList_Length(list); index++)
  27.     {
  28.         p = (int*)SeqList_Get(list,index);
  29.         printf("%d\n",*p);    
  30.     }
  31.     p= NULL;
  32.     printf("\n");
  33.     
  34.     while( SeqList_Length(list) > 0)
  35.     {
  36.         p = (int*)SeqList_Delete(list, 0);
  37.         printf("%d\n",*p);    
  38.     }
  39.     
  40.     SeqList_Destroy(list);
  41.     
  42.     return 0;
  43. }

知识点: void C程序封装;

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


阅读(592) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~