现在数据结构学到了第6章了,现在对以前的各种基本的数据结构做下总结:首先是线性表,线性表是n个数据元素的有限序列,它又包括顺序表和链表。线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,其动态分配存储结构可如下表示: #define LIST_INIT_SIZE 100 //存储空间的初始分配量 #define LISTINCERMENT 10//存储空间的分配增量 typedef struct { ElemType *elem; int length; int listsize; }顺序表的构造不太难,只要给elem一个指向存储空间的值即可,其他的操作不用多说大家应该都知道。以下主要浅谈下链表,最开始其实链表应该是在大一就学的,由于某些原因而错过了,寒假在家自己看了下C中的这一章,所以今年开始学这个时感觉不是太费力,但这也给自己带来了不小麻烦,以至课程讲到第四章时自己又重新回到前面去看线性表。开始学时只是想到这个东西是怎么样的,没有去深入研究它为什么是这样的,当时也是仗着自己先看过的,幸亏现在发现得早自己的错误。 链表与线性表相比最大的特点就是它是用一组任意的存储单元来储存线性表的数据元素,储存单元可以连续也可以不连续。因此为了表示没个数据元素与其后继元素之间的逻辑关系,对每一个数据元素来说除了存储其本身的信息外,还需要一个存储一个指向其直接后继的信息。这两部分信息组成了数据元素的存储映象,即结点(Node)。它包括数据域和指针域。单链表的存储结构可表示如下:typedef struct{ ElemType data; struct LNode *next;}LNode,*LinkList;下面附上其各种操作的C源代码:#include<stdio.h>#include<malloc.h>#include<conio.h>#define ERROR 0#define OK 1#define EQUAL 1#define OVERFLOW -1#define LIST_INIT_SIZE 100#define LISTINCREMENT 10struct STU{ char name[20]; char stuno[10]; int age; int score;}typedef struct STU ElemType;struct LNODE{ ElemType data; struct LNODE *next;};typedef struct LNODE LNode;typedef struct LNODE *LinkList;int init(LinkList *L){ *L=(LNode *)malloc(sizeof(LNode)); if(!L) exit(ERROR); (*L)->next=NULL; return OK;}/*init */int ListLength(LinkList L){ int j=0; while (L->next) { L=L->next; j++; } return j;}int GetElem(LinkList L,int i,ElemType *e){ LinkList p; int j; p=L->next;j=1; while(p&&j<i){ p=p->next;++j; } if(!p||j>1) return ERROR; *e=p->data; return OK;}int EqualList(ElemType *e1,ElemType *e2){ if (strcmp(e1->name,e2->name)==0) return 1; else return 0;}int Less_EqualList(ElemType *e1,ElemType *e2){ if (strcmp(e1->name,e2->name)<=0) return 1; else return 0;}int LocateElem(LinkList La,ElemType e,int type){ int i; LinkList p; p=La; switch (type) { case EQUAL: while(p->next) { p=p->next; if(EqualList(&p->data,&e)) return 1; } return 0; break; default: break; } return 0;}void MergeList(LinkList La,LinkList Lb,LinkList *Lc){ LinkList pa,pb,pc; pa=La->next;pb=Lb->next; *Lc=pc=La; while(pa && pb) { if(Less_EqualList(&pa->data,&pb->data)) { pc->next=pa;pc=pa;pa=pa->next; } else { pc->next=pb;pc=pb;pb=pb->next; } } pc->next=pa?pa:pb; free(Lb);}int printlist(LinkList L){ int i; LinkList p; p=L; printf("name stuno age score\n"); while(p->next) { p=p->next; printf("%-10s %s\t%d\t%d\n", p->data.name, p->data.stuno, p->data.age, p->data.score); } printf("\n");}int ListInsert(LinkList L,int i,ElemType e){ LinkList p,s; int j; p=L;j=0; while(p&&j<i-1) { p=p->next; ++j; } if(!p||j>i-1) return ERROR; s=(LinkList)malloc(sizeof(LNode)); s->data=e; s->next=p->next; p->next=s; return OK;}/*ListInsert Before i */上面的初始化链表操作开始看时很有点迷惑,因为用LinkList定义的变量本来就是就是一个指向该链表的指针,为什么还要int init(LinkList *L)这样定义呢,这里的L应该是指针的指针,显然L是要被回带的吧,我当时也是这样想的,如是int init(LinkList L)就这样难道指针不能回代吗,可能有些人开始也会这么想,其实这样是不行的。因为我们以前在C语言里学过要使被调用函数的型参回代必须直接或间接用到指针,以前我们这样用时被回代的值都是都是普通变量,而这里被回代的值是指针所以要用指针的指针。

评论