线性表
来源:互联网 发布:建行软开待遇 知乎 编辑:程序博客网 时间:2024/05/21 01:55
线性表:顺序表和链表六种基本操作:
InitList(&L) //构造一个空的线性表L
ListLength(L) //获取线性表L的元素个数
GetNode(L, i) //获取线性表L第i个元素
LocateNode(L, e) //查找线性表值为e的元素的位置
ListInsert(L, i, &e) //在线性表L的第i个位置插入元素e
DeleteNode(L, i) //删除线性表L的第i个元素
一、顺序表
#define OK 1#define ERROR -1#define MAX_SIZE 100 //MAX_SIZE大小需根据具体情况而定,这里假设是100#typedef int Status;#typedef int ElemType;typedef struct sqlist{ ElemType Elem_array[MAX_SIZE]; int length;}SqList;
1.1 初始化
Status Init_SqList(SqList *L){ L->Elem_array = (ElemType *)malloc(MAX_SIZE*sizeof(ElemType)); if(!L->Elem_array) return ERROR; else { L->length = 0; return OK; }}
1.2 查找
int Locate_SqList(SqList *L, ElemType x) { int i=0; while(i<L->length) if(L_Elem_array[i] != x) i++; else return ++i; //要查找的值在线性表L第++i个位置 if(i>L->length) { printf(“要删除的数据元素不存在!\n”); return ERROR; }}
1.3 插入
Status Insert_SqList(SqList *L, int i, ElemType e) //在顺序表L中第i个位置插入元素e{ int j; if(i<0||i>L->length-1) return ERROR; if(L->length>=MAX_SIZE) { printf("线性表溢出!\n"); return ERROR; } for(j=L->length-1; j>=i-1; --j) L->Elem_array[j+1] = L->Elem_array[j]; //i-1位置以后的所以结点后移 L->Elem_array[i-1] = e; //在i-1位置插入结点e L->length++; return OK;}
1.4 删除
ElemType Delete_SqList(SqList *L, int i){ int k; ElemType x; if(L->length == 0) { printf("线性表L为空!\n"); return ERROR; } else if(i<1||i>L->length) { printf("要删除的数据元素不存在!\n"); return ERROR; } else { x = L->Elem_array[i-1]; //保存结点的值 for(k=i; k<L->length; k++) L->Elem_array[k-1] = L->Elem_array[k]; //i位置以后的所有结点前移 L->length--; return x; }}
二、单链表
typedef struct Lnode{ ElemType data; //数据域,保存结点的值 struct Lnode *next; //指针域}LNode; //结点类型
2.1 头插入法建表
/*头插入法创建单链表,链表的头结点head作为返回值*/LNode *create_LinkList(void){ int data; LNode *head, *p; head = (LNode *)malloc(sizeof(LNode)); head->next = NULL; //创建单链表头结点head while(1) { scanf("%d", &data); //data值和类型可以根据具体情况得到 if(data == 32767) //32767定义为判断创建链表结束条件 break; p = (LNode *)malloc(sizeof(LNode)); p->data = data; //数据域赋值 p->next = head->next; head->next = p; //钩链,新创建的结点总是作为第一个结点 } return head;}
2.2 尾插入法建表
/*尾插入法创建单链表,链表的头结点head作为返回值*/LNode *create_LinkList(void){ int data; LNode *head, *p, *q; head = p = (LNode *)malloc(sizeof(LNode)); p->next = NULL; //创建单链表头结点head while(1) { scanf("%d", &data); //data值和类型可以根据具体情况得到 if(data == 32767) //32767定义为判断创建链表结束条件 break; q = (LNode *)malloc(sizeof(LNode)); q->data = data; //数据域赋值 q->next = p->next; p->next = q; p = q; //钩链,新创建的结点总是作为第一个结点 } return head;}
2.3 按序号查找
Elem_Type Get_Node(LNode *L, int i) //在单链表L中查找第i个结点{ int j; LNode *p; p = L->next; j = 1; //使p指向第一个结点 while(p!=NULL && j<i) //p为NULL表示i太大;j>i表示i为0; { p = p->next; j++; //移动指针p,j计数 } if(j!=i) return -32768; else return p->data;}
2.4 按值查找
LNode *Locate_Node(LNode *L, int key) //在单链表L中查找值为key的结点{ LNode *p = L->next; while(p!=NULL && p->data != key) p = p->next; if(p->data == key) return p; else { printf("所要查找的结点不存在!\n"); return NULL; }}
2.5 插入
/*在以L为头结点的单链表的第i个位置插入值为e的结点*/void Insert_LNode(LNode *L, int i, ElemType e){ int j = 0; LNode *p, *q; p = L->next; while(p!=NULL && j<i-1) { p = p->next; j++; } if(j!=i-1) printf("i太大或i为0!\n"); else { q = (LNode *)malloc(sizeof(LNode)); q->data = e; q->next = p->next; p->next = q; }}
2.6 按序号删除
/*删除以L为头结点的单链表中的第i个结点*/void Delete_LinkList(LNode *L, int i){ int j=1; LNode *p = L, *q = L->next; while(p->next!=NULL && j<i) { p = q; q = q->next; j++; } if(j!=i) printf("i太大或i为0!\n"); else { p->next = q->next; free(q); }}
2.7 按值删除
/*删除以L为头结点的单链表中值为key的第一个结点*/void Delete_LinkList(LNode *L, int key){ LNode *p = L, *q = L->next; while(q!=NULL && q->data!=key) { p = q; q = q->next; } if(q->data == key) { p->next = q->next; free(q); } else printf("所要删除的结点不存在!\n");}
/*按值删除值为key的所有结点*/void Delete_LinkList_Node(LNode *L, int key){ LNode *p = L, *q = L->next; while(q!=NULL) { if(q->data==key) { p->next = q->next; free(q); q = p->next; } else { p = q; q = q->next; } }}
/*删除以L为头结点的单链表中所有值相同的结点*/void Delete_Node_value(LNode *L){ LNode *p = L->next, *q, *ptr; while(p!=NULL) //检查链表中所有结点 { q = p; ptr = p->next; while(ptr != NULL) //检查结点p的所有后继结点ptr { if(ptr->data == p->data) { q->next = ptr->next; free(ptr); ptr = q->next; } else { q = ptr; ptr = ptr->next; } } p = p->next; }}
2.8 合并
/*合并以La,Lb为头结点的两个有序单链表*/LNode *Merge_LinkList(LNode *La, LNode *Lb){ LNode *Lc, *pa, *pb, *pc, *ptr; Lc = La; pc = La; pa = La->next; pb = Lb->next; while(pa!=NULL &&pb!=NULL) { //将pa所指的结点合并,pa指向下一个结点 if(pa->data < pb->data) { pc->next = pa; pc = pa; pa = pa->next; } //将pb所指的结点合并,pb指向下一个结点 if(pa->data > pb->data) { pc->next = pb; pc = pb; pb = pb->next; } //将pa所指的结点合并,pb所指的结点删除 if(pa->data == pb->data) { pc->next = pa; pc = pa; pa = pa->next; ptr = pb; pb = pb->next; free(ptr); } } if(pa != NULL) pc->next = pa; else pc->next = pb; //将剩余的结点链上 free(Lb); return Lc;}
三、循环链表
判断是否空链表: head->next == head;
判断是否表尾结点: p->next == head;
四、双向链表
typedef struct Dulnode{ ElemType data; struct Dulnode *prior, *next;}DulNode;
4.1 插入
- 插入时仅仅指出直接前驱结点,钩链时必须注意先后次序是:“先右后左”。部分语句组如下:
S = (DulNode *)malloc(sizeof(DulNode));S->data = e;S->next = p->next;p->next->prior = S;p->next = S;S->prior = p;
插入时同时指出直接前驱结点p和直接后继结点q,钩链时无须注意先后次序。部分语句组如下:
S = (DulNode *)malloc(sizeof(DulNode));S->data = e;p->next = S;S->next = q;S->prior = p;q->prior = S;
4.2 删除
设要删除的结点为p,删除时可以不引人新的辅助指针变量,可以直接先断链,再释放结点。部分语句组如下:
p->prior->next = p->next;p->next->prior = p->prior;free(p);