码迷,mamicode.com
首页 > 其他好文 > 详细

线性表

时间:2015-08-04 20:46:27      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

线性表(linear_list)是最常用且最简单的一种数据结构。

一个线性表是n个数据元素的有限序列,它有两种表示形式:顺序表示跟链式表示。

 

线性表的顺序表示和实现

线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种数据结构称之为顺序表

技术分享

下面顺序表的一种实现

技术分享
  1 #include <stdio.h>
  2 #include <malloc.h>
  3 #include <stdbool.h>
  4 #define OK 1
  5 #define ERROR 0
  6 #define OVERFLOW -1 
  7 #define LIST_INIT_SIZE 100     //线性表存储空间的初始分配量 
  8 #define LISTINCREMENT 10       //线性表存储空间的分配增量  
  9 
 10 typedef char ElemType;
 11 typedef struct
 12 {
 13     ElemType *elem;     //存储空间的基址 
 14     int length;         //当前长度 
 15     int listsize;       //当前分配的存储容量(以sizeof(ElemType)为单位) 
 16 }SqList;
 17 
 18 //初始化顺序表 
 19 int InitList(SqList &L)
 20 {
 21     L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
 22     if(!L.elem)  return OVERFLOW;  //存储分配失败 
 23     L.length=0;                    //空表长度为0 
 24     L.listsize=LIST_INIT_SIZE;     //初始存储容量 
 25     return OK;
 26 }
 27 
 28 //销毁顺序表
 29 void DestroyList(SqList &L)
 30 {
 31     free(L.elem);
 32 } 
 33 
 34 //在顺序表L中第i个位置之前插入新的元素e 
 35 int ListInsert(SqList &L,int i,ElemType e)
 36 {
 37     //i的合法值为1≤i≤L.length+1 
 38     if(i<1||i>L.length+1)  return ERROR;  
 39     //当前存储空间已满,重新分配空间 
 40     if(L.length>=L.listsize)
 41     {
 42         ElemType *newbase=NULL;
 43         newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
 44         if(!newbase)  return OVERFLOW;
 45         L.elem=newbase;
 46         L.listsize+=LISTINCREMENT; 
 47     }
 48     //p为插入位置
 49     ElemType *p=&(L.elem[i-1]);
 50     //插入位置及之后的元素右移  q为最后一个元素的位置 
 51     for(ElemType *q=(L.elem+L.length-1);q>=p;--q)  *(q+1)=*q; 
 52     *p=e;              //插入e 
 53     ++L.length;         //表长加1 
 54 }
 55 
 56 //在顺序表L中删除第i个元素,并用e返回其值
 57 int ListDelete(SqList &L,int i,ElemType &e)
 58 {
 59     //i的合法值为1≤i≤L.length
 60     if(i<1||i>L.length)  return ERROR;
 61     ElemType *p=&(L.elem[i-1]);    //p为被删除位置元素的位置 
 62     e=*p;                          //将删除元素的值赋给e 
 63     ElemType *q=L.elem+L.length-1; //q为表尾元素的位置
 64     for(;p<=q;++p)    *p=*(p+1);
 65     --L.length;
 66     return OK; 
 67 }
 68 
 69 
 70 //判断顺序表是否为空表 
 71 bool ListEmpty(SqList &L)
 72 {
 73     return (L.length==0);
 74 } 
 75 
 76 //求顺序表的长度
 77 int ListLength(SqList &L)
 78 {
 79     return (L.length);
 80 } 
 81 
 82 //输出顺序表
 83 void DispList(SqList &L)
 84 {
 85     if(ListEmpty(L))  return;
 86     for(int i=0;i<L.length;++i)
 87         printf("%c",L.elem[i]);
 88     printf("\n");
 89 } 
 90 
 91 //获取顺序表中索引位置的元素值
 92 bool GetElem(SqList &L,int i,ElemType &e)
 93 {
 94     if(i<1||i>L.length)  return false;
 95     e=L.elem[i-1];
 96     return true; 
 97 } 
 98 
 99 //按元素值查找
100 int LocateElem(SqList &L,ElemType e)
101 {
102     int i=0;
103     //查找元素e 
104     while(i<L.length&&L.elem[i++]!=e);
105     //未找到 
106     if(i>L.length)  return -1;
107     return i; 
108 } 
View Code

 

 

线性表的链式表示和实现

线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。

为了表示元素之间的逻辑(先后)关系,对于任一数据元素,除了存储元素本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。

每个数据元素包含两个域:其中存储数据元素信息的域称为数据域,存储直接后继存储位置的域称为指针域

技术分享

下面是单链表(带头节点)的一种实现

技术分享
  1 #include <stdio.h>
  2 #include <malloc.h>
  3 typedef char ElemType;
  4 //定义单链表节点类型 
  5 typedef struct LNode
  6 {
  7     ElemType data;
  8     struct LNode *next;
  9 }LinkList;
 10 
 11 //初始化 
 12 void InitList(LinkList *&L)
 13 {
 14     //创建头节点 
 15     L=(LinkList *)malloc(sizeof(LinkList));
 16     L->next=NULL;
 17 } 
 18 
 19 //销毁单链表
 20 void DestroyList(LinkList *&L)
 21 {
 22     LNode *p=L;
 23     LNode *q=p->next;
 24     while(q!=NULL)
 25     {
 26         free(p);
 27         p=q;
 28         q=q->next;
 29     }
 30     free(p);
 31 } 
 32 
 33 //判断是否为空表
 34 bool ListEmpty(LinkList *L)
 35 {
 36     return  (L->next==NULL);
 37 } 
 38 
 39 //求单链表的长度
 40 int ListLength(LinkList *L)
 41 {
 42     int i=0;
 43     LNode *p=L;
 44     while(p->next!=NULL)
 45     {
 46         i++;
 47         p=p->next;
 48     }
 49     return i;
 50 } 
 51 
 52 //输出单链表
 53 void DispList(LinkList *L)
 54 {
 55     LNode *p=L->next;
 56     while(p!=NULL)
 57     {
 58         printf("%c",p->data);
 59         p=p->next;
 60     }
 61     printf("\n");
 62 } 
 63 
 64 //按逻辑索引值找数据元素值  该值通过e返回 
 65 bool GetElem(LinkList *L,int i,ElemType &e)
 66 {
 67     int j=0;
 68     LNode *p=L;
 69     while(j<i&&p!=NULL)
 70     {
 71         j++;
 72         p=p->next;
 73     }
 74     if(p==NULL)
 75         return false;
 76     e=p->data;
 77     return true;
 78 } 
 79 
 80 //按元素值查找逻辑索引值
 81 int LocateElem(LinkList *L,ElemType e)
 82 {
 83     LNode *p=L->next;
 84     int i=1;
 85     while(p!=NULL&&p->data!=e)
 86     {
 87         i++;
 88         p=p->next;
 89     }
 90     if(p==NULL)
 91         return 0;
 92     return i;
 93 } 
 94 
 95 //插入数据元素
 96 bool ListInsert(LinkList *&L,int i,ElemType e)
 97 {
 98     int j=0;
 99     LNode *p=L;
100     //找到索引为i-1的节点 
101     while(j<i-1&&p!=NULL)
102     {
103         j++;
104         p=p->next;
105     }
106     if(p==NULL)
107         return false;
108     LNode *node=(LNode *)malloc(sizeof(LNode));
109     node->data=e;
110     node->next=p->next;
111     p->next=node;
112     return true; 
113 }
114 
115 //删除数据元素
116 bool ListDelete(LinkList *&L,int i,ElemType &e)
117 {
118     int j=0;
119     LNode *p=L;
120     //找到索引为i-1的节点 
121     while(j<i-1&&p!=NULL)
122     {
123         j++;
124         p=p->next;
125     }
126     //未找到第i-1个节点 
127     if(p==NULL)
128         return false;
129     //不存在第i个节点 
130     if(p->next==NULL)
131         return false;
132     //记录要删除的节点 
133     LNode *q=p->next;
134     e=q->data;
135     p->next=q->next;
136     free(q);
137     return true;
138 } 
View Code

 

双链表中的元素比单链表的元素多出一个指针域,这个指针域指向该元素的前驱。

双链表的实现跟单链表类似,只是多出了对前驱指针域的操作。

技术分享

下面是双链表(带头节点)的一种实现(只给出与单链表不同的代码)

技术分享
 1 #include <stdio.h>
 2 #include <malloc.h>
 3 typedef char ElemType;
 4 //定义双链表节点类型
 5 typedef struct DNode
 6 {
 7     ElemType data;
 8     struct DNode *prior;
 9     struct DNode *next;
10 }DLinkList;
11 
12 //初始化
13 void InitList(DLinkList *&L)
14 {
15     //创建头结点 
16     L=(DLinkList *)malloc(sizeof(DLinkList));
17     L->prior=L->next=NULL;
18 } 
19 
20 //插入数据元素
21 bool ListInsert(DLinkList *&L,int i,ElemType e)
22 {
23     int j=0;
24     DNode *p=L;
25     //找到索引为i-1的节点 
26     while(j<i-1&&p!=NULL)
27     {
28         j++;
29         p=p->next;
30     }
31     if(p==NULL)
32         return false;
33     //将*node插入到*p之后 
34     DNode *node=(DNode *)malloc(sizeof(DNode));
35     node->data=e;
36     node->next=p->next;
37     //如果*p不是最后一个节点 
38     if(p->next!=NULL)
39         p->next->prior=node;
40     p->next=node;
41     node->prior=p;
42     return true; 
43 } 
44 
45 //删除数据元素
46 bool ListDelete(DLinkList *&L,int i,ElemType &e) 
47 {
48     int j=0;
49     DNode *p=L;
50     //找到索引为i-1的节点 
51     while(j<i-1&&p!=NULL)
52     {
53         j++;
54         p=p->next;
55     }
56     //未找到第i-1个节点 
57     if(p==NULL)
58         return false;
59     //不存在第i个节点 
60     if(p->next==NULL)
61         return false;
62     //删除*q节点
63     DNode *q=p->next;
64     e=q->data;
65     p->next=q->next;
66     //如果*q不是最后一个节点 
67     if(q->next!=NULL)    
68         q->next->prior=q->prior;
69     free(q);
70     return true;
71 }
View Code

 

循环链表是另一种形式的链式存储的结构,它的特点是表中最后一个节点的指针域指向头节点,整个链表形成一个环。

下图是一个循环单链表

技术分享

下图是一个循环双链表

技术分享

 

线性表

标签:

原文地址:http://www.cnblogs.com/runnyu/p/4702415.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!