温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

数据结构基础(一)

发布时间:2020-07-02 23:23:17 来源:网络 阅读:1915 作者:酥心糖 栏目:开发技术

线性表

线性顺序表

1、线性表的数据操作

数据结构基础(一)

2、使用定义的函数实现两个集合LA和LB的合并:

void unionList(List LA,List LB,List &LC) { int lena,i; ElemType e; InitList(LC); //将LA的所有元素插入到LC中 for (i=1;i<=ListLength(LA);i++) { GetElem(LA,i,e); ListInsert(LC,i,e); } lena=ListLength(LA); //将LB的所有元素插入到LC for(i=1;i<ListLength(LB);i++) { GetElem(LB,i,e); if (!LocateElem(LA,e)) ListInsert(LC,++lena,e); } } 

3、顺序表存储类型的定义

# define MaxSize 50 typedef struct { ElemType date[MaxSize]; int length; }SqList; 

4、创建线性表

void CreateList(Sqlist *&L,ElemType a[],int n) { int i; L=(SqList *)malloc(sizeof(SqList)); // malloc 相当于new,分配SqList大小的内存空间,指向SqLost的指针,并将地址赋值给L for (i=0;i<n;i++) L->data[i]=a[i]; L->length=n; }

5、初始化线性表

void InitList(SqList *&L) // 应用指针 { L=(SqList *)malloc(sizeof(SqList)); L->length=0; // 初始化线性表的长度 } 

6、销毁线性表

void DestroyList(SqlList *&L) { free(L); } 

7、判断线性表是否为空

bool ListEmpty(SqList *L) { return(L->length==0); } 

8、求线性表的长度

int ListLength(SqList *L) { return(L->length); } 

9、输出线性表

void DispList(SqList *L) { int i; if (ListEmpty(L)) return; for (i=0;i<L->length;i++) printf("%d ",L->data[i]); printf("\n"); }

10、求某个数据元素的值,返回L中的第i个元素的值,并存入e中,1<=i<=ListLength(L)

bool GetElem(SqList *L,int i,ElemType &e) { if (i<1||i>L->length) return false; e=L->data[i-1]; return true; }

11、按元素值查找

int LocateElem(L,e) { int i = 0; while (i<L->length && L->data[i]!=e) i++; if (i>=L->length) return 0; else return i+1; } 

12、插入元素

bool ListInsert(SqList *&L,int i,ElemType e) { int j; if (i<1||i>L->length+1) return false; i--; for (j=L->length;j>i;j--) L->data[j]=L->data[j-1]; L->data[i]=e; L->length++; return true; } 

13、删除元素

bool ListDelete(SqList *&L,int i,ElemType &e) { int j; if (i<1||i>L->length) return false; i--; e=L->data[i]; for(j=i;j<L->length-1;j++) L->data[j]=L->data[j+1]; L->length--; return true; } 
线性链表

1、单链表的存储结构的定义

typedef struct LNode // 定义单链表节点类型 { ElemType data; //数据域 struct LNode *next; //指针域,指向后继节点 递归结构 }LinkList;

2、单链表的头插法:

void CreateListF(LinkList *&L,ElemType a[],int n) { LinkList *S; int i; L=(LinkList *)malloc(sizeof(LinkList)); L->next=NULL; for(i=0;i<n;i++) { S=(LinkList *)malloc(sizeof(LinkList)); S->data=a[i]; S->next=L->next; L->next=S; } } 

3、单链表尾插法

void CreateListR(LinkList *&L,ElemType a[],int n) { LinkList *s,*r; int i; L=(LinkList *)malloc(sizeof(LinkList)); r=L; for(i=0;i<n;i++) { s=(LinkList *)malloc(sizeof(LinkList)); s->data=a[i]; r->next=s; r=s; } r->next=NULL; } 

4、单链表的基本操作

数据结构基础(一)

5、初始化线性表

void InitList(LinkList *&L) { L=(LinkList *)malloc(sizeof(LinkList)); L->next=NULL; }

6、销毁线性表

void DestroyList(LinkList *&L) { LinkList *pre=L,*p=L->next; while (p=NULL) { free(pre); pre=p; p=pre->next; } free(pre); } 

7、判断表为空

bool ListEmpty(LinkList *L) { return(L->next==NULL); }

8、求线性表的ListLength(L)

 int ListLength(LinkList *L) { int n=0; LinkList *p=L; while (p->next!=NULL) { n++; p=p->next; } return(n); }

9、输出线性表:

void DisList(LinkList *L) { LinkList *p=L->next; while(p!=NULL) { printf("%d",p->data); p=p->next; } printf("\n") } 

10、查找某个元素

bool GetElem(LinkList *L,int i,ElemType &e) { int j=0; LinkList *p=L; while (j<i&&p!=NULL) { j++; p=p->next; } if (p==NULL) return false; else { e=p->data; return true; } }

11、 按元素查找,返回元素的位置

 int LocateElem(LinkList *L,ElemType e) { int i=1; LinkList *p=L->next; while (p!=NULL&& p->data!=e) { p=p->next; i++; } if (p==NULL) return 0; else return i; } 

12、插入数据元素:

 bool ListInsert(LinkList *&L,int i,ElemType e){ int j=0; LinkList *p=L,*S; while (j<i-1 && p!=NULL){ j++; p=p->next; } if (p==NULL) return false; else{ S=LinkList *)malloc(sizeof(LinkList)); S->data=e; S->next=p->next; p->next=S; return true; } }

13、删除数据元素

 bool ListDelete(LinkList *&L,int i,ElemType &e) { int j=0; LinkList *p=L,*q; while(j<i-1 && p!=NULL){ j++; p=p->next; } if (p==NULL) return false; else{ q=p->next; if(q=NULL) return false; e=q->data; p->next=q->next; free(q); return true; } } 
双链表

1、双向链表的定义和存储结构

 typedef struct DNode { ElemType data; struct DNode *prior; struct DNode *next; }DLinkList;

2、头插法建立双链表

{ DLinkList *S; int i; L=(DLinkList *)malloc(sizeof(DLinkList)); L->prior=L->next=NULL; for(i=0;i<n;i++) { S=(DLinkList *)malloc(sizeof(DLinkList)); S->data=a[i]; S->next=L->next; if(L->next!=NULL) L->next->prior=S; L->next=S; S->prior=L; } } 

3、尾插法建立双链表

 void CreateListR(DLinkList *&L,ElemType a[],int n) { DLinkList *s,*r; int i; L=(DLinkList *)malloc(sizeof(DLinkList)); r=L; for (i=0;i<n;i++) { s=(DLinkList *)malloc(sizeof(DLinkList)); s->data=a[i]; r->next=s; s->prior=r; r=s; } r->next=NULL; }

4、插入节点:

 bool ListInsert(DLinkList *&L,int i,ElemType e) { int j=0; DLinkList *p=L,*s; while(j<i-1 && p!=NULL) { j++; p=p->next; } if (p=NULL) return false; else { s=(DLink *)malloc(sizeof(DLinkList)); s->data=e; s->next=p->next; if (p->next!=NULL) P->next->prior=s; s->prior=p; p->next=s; return true; } }

5、双链表删除节点

 bool ListDelete(DLinkList *&L,int i,ElemType &e) { int j=0; DLinkList *p=L, *q; while (j<i-1 && p!=NULL) { j++; p=p->next; } if (p==NULL) return false; else { q=p->next; if (q==NULL) return false; e=q->data; p->next=q->next; if (p->next!=NULL) p->next->prior=p; free(q); return true; } }
有序表的操作

1、有序顺序表的插入操作:

 void ListInsert(SqList *&L,ElemType e) { int i =0,j; while (i<L->length && L->data[i]<e) i++; for (j=ListLength(L);j>i;j--) L->data[j]=L->data[j-1]; L->data[i]=e; L->length++; }

2、有序链表的插入操作:

 void ListInsert(LinkList *&L,ElemType e) { LinkList *pre=L, *p; while (pre->next!=NULL && pre->next->data < e) pre=pre->next; p=(LinkList *)malloc(sizeof(LinkList)); p->data=e; p->next=pre->next; pre->next=p; }

3、采用顺序表存放有序表时的归并算法(将顺序表LA和LB中的元素插入到LC中形成一个新的顺序表):

void UnionList(SqList *LA,SqList *LB,SqList *&LC) { int i=0,j=0,k=0; LC=(SqList *)malloc(sizeof(SqList)); // LA和LB均未达到末尾时,择其小加入LC while(i<LA->length && j<LB->length) { if(LA->data[i]<LB->data[j]) { LC->data[k]=LA->data[i]; i++; } else { LC->data[k]=LB->data[j]; j++; } k++; } // LA 尚未扫描完,将其余元素插入LC中 while(i<LA->length) { LC->data[k]=LA->data[i]; i++; k++; } while(j<LB->length) { LC->data[k]=LB->data[j]; j++; k++; } }

4、采用单链表存放有序表时的归并算法(将有序链表LA和LB中的元素插入到LC中形成一个新的有序链表):

void UnionList1(LinkList *LA,LinkList *LB,LinkList *&LC) { LinkList *pa=LA->next, *pb=LB->next, *r,*s; LC=(LinkList *)malloc(sizeof(LinkList)); r=LC; // LA 和 LB 均未达到末尾时,择其小优先尾插 while(pa!=NULL && pb!=NULL) { S=(LinkList *)malloc(sizeof(LinkList)); if(pa->data<pb->data) { s->data=pa->data; pa=pa->next; } else { s->data=pb->data; pb=pb->next; } r->next=s; r=s; } // LA 未达到末尾,复制LA中所有结点 while(pa!=NULL) { s=(LinkList *)malloc(sizeof(LinkList)); s->data=pa->data; r->next=s; r=s; pa=pa->next; } // LB 未达到末尾,复制LA中所有结点 while(pb!=NULL) { s=(LinkList *)malloc(sizeof(LinkList)); s->data=pb->data; r->next=s; r=s; pb=pb->next; } }

栈和队列

1、栈的判定:

  • 栈空: top = -1
  • 栈满: top = MaxSize-1
  • 进栈e操作:top ++ ; 将e放在top处
  • 退栈操作:从top处取出元素e; top --;

2、初始化一个空栈s,实际上是将栈顶指针指向-1即可。

// 定义一个顺序栈 typedef struct { ElemType data[MaxSize]; int top; }SqStack; void InitStack(SqStack *&s) { s=(SqStack *)malloc(sizeof(SqStack)); // 申请内存空间 s->top=-1; }

3、释放栈s占用的空间,销毁栈:

void DestoryStack(SqStack *&s) { free(s); } 

4、进栈操作push(&s,e)

  • 条件:在栈不满时,可以进栈
  • 操作:
    • 将栈指针+1
    • 在该位置上插入元素e
bool Push(SqStack *&s,ElemType e) { if (s->top==MaxSize-1) return false; // 栈满 s->top++ s->data[s->top]=e; return true; } 

5、Pop(&s,&e)出栈

  • 条件: 栈不为空
  • 操作:
    • 栈顶元素赋值给e
    • 指针减1
bool Pop(SqStack *&s,ElemType &e) { if (s->top==-1) return false; e=s->data[s->top]; s->top--; return true; }

6、用栈判断对称串算法

bool summetry(ElemType str[]) { int i; ElemType e; SqStack *st; InitStack(st); // 将所有元素进栈 for (i=0;str[i]!='\0';i++) Push(str,str[i]); // 出栈的字符与从左向右读取的字符串比较 for(i=0;str[i]!='\0';i++) { Pop(st,e); if(str[i]!=e) { DestroyStack(st); return false; } } DestroyStack(st); return true; } 
栈的链式存储结构

1、栈的链式存储

 * 采用单链表: 头结点后保存栈顶 * 优点:不存在栈满上溢的情况 * 栈空条件: s->next=NULL

定义:

typedef struct linknode { ElemType data; struct linknode *next; }LiStack; 

2、建立一个空栈

void InitStack(LiStack *&s) { s=(LiStack *)malloc(sizeof(LiStack)); s->next=NULL; } 

3、释放栈的全部占用空间

 void DetroyStack(LiStack *&s) { LiStack *p=s, *q=s->next; while (q!=NULL) { free(p); p=q; q=p->next; } free(p); }

4、判断栈是否为空

 bool StackEmpty(LiStack *S) { return(s->next==NULL); }

5、进栈

 void Push(LiStack *&s,ElemType e) { LiStack *p; p=(LiStack *)malloc(sizeof(LiStack)); p->data=e; p->next=s->next; s->next=p; } 

6、 出栈

 bool Pop(LiStack *&s, ElemType &e) { LiStack *p; if (s->next==NULL) return false; p=s->next; e=p->data; s->next=p->next; free(p); return true; }

7、取栈顶元素

 bool GetTop(LiStack *s,ElemType &e) { if (s->next==NULL) return false; e=s->next->data; return true; }
队列

队列的数据操作:

  • InitQueue(&q): 初始化队列,构造一个新队列
  • DestroyQueue(&q): 销毁队列。
  • QueueEmpty(q):判断队列是否为空
  • enQueue(&q,e): 进队列。将元素e进队,作为队尾元素。
  • deQueue(&q,&e): 出队列。

队列的存储结构:

  • 数据元素data : 元素具有同一类型ElemType.最多Maxsize
  • 当前队首: front
  • 当前队尾:rear

定义结构:

typedef struct { ElemType data[MaxSize]; int front,rear; //队首和队尾指针 } SqQueue; 

1、顺序队的特性

  • 队空条件: front = rear
  • 队满条件: rear = MaxSize - 1
  • 元素e进队: rear ++; data[rear]=e;
  • 元素e出队: front ++; e=data[front];
  • rear指向队尾元素
  • front指向队头元素的前一个位置

2、初始化队列

 void InitQueue(SqQueue *&q) { q=(SqQueue *)malloc(sizeof(SqQueue)); q->front=q->rear=-1; }

3、释放队列q所占的存储空间

 void DestroyQueue(SqQueue *&q) { free(q); }

4、判断队列是否为空QueueEmpty

bool QueueEmpty(SqQueue *q) { return(q->front==q->rear); }

5、进队列

bool enQueue(SqQueue *&q,ElemType e) { if (q->rear==MaxSize-1) return false; q->rear++ q->data[q->rear]=e; return true; }

6、出队列

bool deQueue(SqQueue *&q,ElemType &e) { if (q->front==q->rear) return false; q->front++; e=q->data[q->front]; return true; } 

提示:顺序队列在满队数据取完后,在队空的情况下会出现front==rear&& rear = MaxSize - 1的情况,而出现这种情况后,无法再插入数据,这就需要使用环形队列。

环形队列
  • 队空条件: front=rear
  • 队满条件:(rear+1)%MaxSize=front
  • 进队e操作: rear=(rear+1)%MaxSize; 将e放在rear处
  • 处队操作:front=(front+1)%MaxSize; 取出front处元素e;
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI