数据结构
线性表
线性表的顺序存储
1. 顺序线性表初始化
长度变为零,数组初始化。
typedef struct Sqlist { int a[MAX_SIZE]; int length; }Sqlist; //*线性表的初始化*/ int Init_Sqlist(Sqlist **list) { (*list)->length=0; }
2. 顺序线性表的插入
(1) 将线性表L中的第i个至第n个结点后移一个位置。 (2) 将结点e插入到结点ai-1之后。 (3) 线性表长度加1。
//*线性表的插入*/ int insert_Sqlist(Sqlist *list,int j,int e) { if(j<0||j>list->length) return ERROR; for(int i=list->length;i>=j-1;i--) { list->a[i]=list->a[i-1]; } list->a[j-1]=e; list->length++; return OK; }
3. 顺序线性表的删除
(1) 将线性表L中的第i+1个至第n个结点依此向前移动一个位置。(2) 线性表长度减1。
//*线性表的删除*/ int delete_Sqlist(Sqlist *list,int i) { if(list->length==0) return ERROR; for(int j=i;j<list->length;j++) { list->a[j-1]=list->a[j]; } list->length--; return OK; }
4. 顺序线性表的查找定位删除
(1) 在线性表L查找值为x的第一个数据元素。(2) 将从找到的位置至最后一个结点依次向前移动一个位置。 (3) 线性表长度减1。
//*线性表的定位删除*/ int Locate_Delete_Sqlist(Sqlist *list,int x) { int i=0,j; while(i<list->length) { if(list->a[i]!=x) i++; else { break; } } if(i==list->length) return ERROR; for(j=i+1;j<list->length;j++) { list->a[j-1]=list->a[j]; } list->length--; return OK; }
线性表的链式存储
1 建立单链表
⑴ 头插入法建表
每次插入的结点都作为链表的第一个结点。
typedef struct Lnode { int data; struct Lnode *next; }Lnode; //* 头插入链表 *// Lnode* Creat_List() { Lnode *head=NULL,*p; while(1) { int m; scanf("%d",&m); if(m==0) break; p=(Lnode *)malloc(sizeof(Lnode)); p->data=m; p->next=head; head=p; } return head; }
(2) 尾插入法建表
新结点插入到当前链表的表尾,使其成为当前链表的尾结点。
//* 尾插入链表 *// Lnode* Creat_List() { Lnode *head,*p,*q=NULL; head=(Lnode *)malloc(sizeof(Lnode)); head->next=q; q=head; while(1) { int m; scanf("%d",&m); if(m==0) break; p=(Lnode *)malloc(sizeof(Lnode)); p->data=m; q->next=p; q=p; } q->next=NULL; return head->next; }
2 单链表的查找
(1) 按序号查找
int search_list(Lnode *head,int j) { int i=0; Lnode *first; for(first=head;first!=NULL,i<j;first=first->next) { i++; } if(first!=NULL) { return first->data; } else { return 0; } }
(2) 按值查找
int search_list(Lnode *head,int key) { Lnode *first; for(first=head;first!=NULL;first=first->next) { if(first->data==key) return first->data; } return 0; }
3 单链表的插入
Lnode* insert_Lnode(Lnode *head,int x,int key) { Lnode *first,*q; int i=2; for(first=head;first!=NULL,i<x;first=first->next) { i++; } q=(Lnode *)malloc(sizeof(Lnode)); q->data=key; if(i==1) { q->next=head; return q; } else { q->next=first->next; first->next=q; } return head; }
4 单链表的删除
⑴ 按序号删除
Lnode* delete_Lnode(Lnode *head,int x) { Lnode *cur,*prew; int i=1; for(cur=head,prew=NULL;cur!=NULL,i<x;prew=cur,cur=cur->next) { i++; } if(cur==NULL) return head; else if(prew==NULL) head=head->next; else { prew->next=cur->next; free(cur); } return head; }
⑵ 按值删除
Lnode* delete_Lnode(Lnode *head,int x) { Lnode *cur,*prew; for(cur=head,prew=NULL;cur!=NULL,cur->data!=x;prew=cur,cur=cur->next) { ; } if(cur==NULL) return head; else if(prew==NULL) head=head->next; else { prew->next=cur->next; free(cur); } return head; }
5 单链表的合并
struct node *merge(struct node *first,struct node *list) { struct node *p,*q,*r,*t; p=first; q=list; r=malloc(sizeof(struct node)); t=r; while(p&&q) { if(p->date<q->date) //< 这里必须要注意,并且要注意排序>; { t->next=p; t=p; p=p->next; } else { t->next=q; t=q; q=q->next; } } if(p) { t->next=p; } if(q) { t->next=q; } return r->next; }
6. 循环链表
对于单循环链表,除链表的合并外,其它的操作和单线性链表基本上一致,仅仅需要在单线性链表操作算法基础上作以下简单修改: ⑴ 判断是否是空链表:head->next==head ; ⑵ 判断是否是表尾结点:p->next==head ;
#include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node *next; }Node; Node *creat_list() { Node *first,*second=NULL,*p; first=malloc(sizeof(Node)); first->next=second; second=first; for(int i=0;i<3;i++) { int m; scanf("%d",&m); p=malloc(sizeof(Node)); p->data=m; second->next=p; second=p; } second->next=first->next; return first->next; } int main() { Node *list=NULL,*q; list=creat_list(); printf("%d ",list->data); for(q=list->next;q!=list;q=q->next) { printf("%d ",q->data); } }
7. 双向链表
void insert(struct node *list,int m,int n) { struct node *p,*q; int i=1; q=(struct node *)malloc(sizeof(struct node)); q->date=n; for(p=list->next;i<m&&p!=list;p=p->next) { i++; } if(p==list&&i<m) { printf("error"); } else { q->prior=p->prior; p->prior->next=q; q->next=p; p->prior=q; } }
双向链表的删除
p->prior->next=p->next; p->next->prior=p->prior; free(p); 注意: 与单链表的插入和删除操作不同的是,在双向链表中插入和删除必须同时修改两个方向上的指针域的指向。