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

来源:互联网 发布:c语言中double 编辑:程序博客网 时间:2024/06/09 18:56

因为已经大三下学期,准备暑假找实习,以前学得渣,这段时间恶补下基础!!数据结构和算法搞起

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

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()释放结点内存空间。
  链式表跟顺序表的优缺点相反,删除插入方便,但不能随机存取。



0 0