您的位置:首页 > 理论基础 > 数据结构算法

数据结构(c)——线性表:顺序表和链式表

2016-04-16 15:26 274 查看
因为已经大三下学期,准备暑假找实习,以前学得渣,这段时间恶补下基础!!数据结构和算法搞起

线性表包括顺序存储和链式存储两种形式。

1、顺序表

首先定义宏,为线性表分配初始内存空间和再分配用
定义结构体,内部定义指针作为线性表的基址,动态分配后就可以用下标访问,跟数组一样,数组a[10],a是指向第一个元素的指针,
#define LIST_INIT_SIZE 100    //首次分配的空间大小
#define LISTINCREMENT  10    //每次再分配增加的存储空间
typedef struct{
char *elem;      //elem是基址
int  length;     //当前表长度
int  listsize;   //当前已分配存储空间大小
}SqList;

声明一个插入的函数,比较有代表性,其他操作就省略了。。
第一个参数传入SqList类型的引用,在函数操作中需修改变量值!
void ListInsert_Sq(SqList &L,int i,char e);

主函数首先声明SqList类型的变量,动态分配100个char型变量的内存空间,返回基址给elem,接着赋值length,listsize,初始化搞定。
main(){
SqList L;
L.elem = (char *)malloc(LIST_INIT_SIZE * sizeof(char));
L.length = 0;
L.listsize = LIST_INIT_SIZE;

ListInsert_Sq(L,1,'a');
    ListInsert_Sq(L,1,'b');
    printf("L.elem[0]:%c, L.elem[1]:%c",L.elem[0],L.elem[1]);
}
插入操作函数实现:
void ListInsert_Sq(SqList &L,int i,char e){
if(i < 1 || i > L.length + 1) return;
if(L.length >= L.listsize){       //分配空间已满
char *newbase;
newbase = (char *)realloc(L.elem,(L.listsize + LISTINCREMENT) * sizeof(char));  //再分配,返回新基址
if(!newbase) exit(0);     //分配失败
L.elem = newbase;
L.listsize += LISTINCREMENT;
}
char *p,*q;
p = &(L.elem[i - 1]);
for(q = &(L.elem[L.length - 1]); p <= q; q--){
*(q + 1) = *(q);      //后面所有元素向后移
}
*p = e;
L.length ++;
}
运行结果:


顺序表各元素在物理上也相邻,优点是能靠下标随机存取,缺点是删除增加一个元素都是移动后面所有元素。

2、链式表

同样首先定义结构体,链式表的每个结点 ,结结结结结点,包含一个基本数据,跟一个指向下一个结点的指针:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

typedef struct LNode{
char          data;
struct LNode  *next;
}LNode,*LinkList;    //LNode是类型,LinkList是指针类型,可用以声明LNode类型的指针变量
声明插入操作函数,有代表性
void ListInsert_L(LinkList &L,int i,char e);  //传指针类型进来,又可能修改头结点值,传引用

结构体指针可用->符号访问结构体的内部元素,p->data等价于(*p).data
NULL定义在头文件stddef.h中,也能自己定义宏,C语言没有空的概念,都是拿一个值替换
主函数
main(){
LNode *head;
head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;  //必须初始化,否则next指针指向随机内存单元,“野指针”
ListInsert_L(head,1,'a');
ListInsert_L(head,1,'b');
for(LinkList p = head->next; p != NULL; p = p->next){
printf("%c\n",p->data);
}
}
void ListInsert_L(LinkList &L,int i,char e){
LNode *p;
LNode *q;
int j = 0;
p = L;
while(p && j < i - 1){
p = p->next;
j ++;
}//找到第i-1个结点
if(!p) return; //i值不合法
q = (LinkList)malloc(sizeof(LNode));
q->next = p->next;
p->next = q;
q->data = e;
}

运行结果:


删除操作需要free()释放结点内存空间。
链式表跟顺序表的优缺点相反,删除插入方便,但不能随机存取。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: