链表操作
2016-04-27 21:54
218 查看
链表操作
这篇文章是上课实验的内容,包括顺序表,链表,以及链表的各种应用。顺序表
顺序表的存储:typedef struct Sqlist { ElemType *slist; int length; int listsize; }Sqlist;
顺序表的各种操作:
/*(2)---线性表的初始化*/ int InitList_sq(Sqlist *L) { L->slist=(ElemType *)malloc(INIT_SIZE * sizeof(ElemType)); if(!L->slist) return ERROR; L->length = 0; L->listsize=INIT_SIZE; return OK; } /*(3)---创建具有n个元素的顺序表*/ int CreateList_sq(Sqlist *L,int n) { for(int i=0;i<n;i++) { L->slist[i]=i; L->length++; if(L->length>=L->listsize) { L->slist=(ElemType*) realloc(L->slist,(L->listsize+INCREM)*sizeof(ElemType)); if(!L->slist) return ERROR; L->listsize+=INCREM; } } return OK; }/*(4)---输出顺序表中的元素*/ /*(5)---在顺序表的第i个位置之前插入新元素e*/ int ListInsert_sq(Sqlist *L,int i,ElemType e) { int k; if(i<1 || i>L->length+1) return ERROR; if(L->length>=L->listsize) { L->slist=(ElemType*) realloc(L->slist,(L->listsize+INCREM)*sizeof(ElemType)); if(!L->slist) return ERROR; L->listsize+=INCREM; } for(k=L->length-1;k>=i-1;k--) L->slist[k+1]=L->slist[k]; L->slist[i-1]=e; L->length++; return OK; } /*(6)---在顺序表中删除第i个元素,e返回删除的元素*/ int ListDelete_sq(Sqlist *L,int i,ElemType *e) { int j; if(i<1 || i>L->length) return ERROR; *e = L->slist[i]; for(j=i;j<L->length;j++) L->slist[j-1] = L->slist[j]; L->length --; return OK; }/* ListDelete_sq */ /*(7)---在顺序表中查找指定值元素,pos为返回其位置序号*/ int ListLocate(Sqlist *L,ElemType e,int *pos) { int i; for(i=0;i<L->length;i++) if(e==L->slist[i]) { *pos = i; return OK; } return ERROR; }/* ListLocate */ int PrintList_sq(Sqlist *L) { int i=0; for(i=0;i<L->length;i++) printf("%d ",L->slist[i]); return OK; }
链表
链表的存储:typedef struct LNode{ ElemType data; struct LNode * next; }LNode,*LinkList;
链表的各种操作:
/*带头结点单链表初始化*/ LNode *InitList(LinkList L) { L=(LNode *)malloc(sizeof(LNode)); /*申请一个头结点*/ if (!L) return ERROR;/*申请失败*/ L->next=NULL; /*头结点的指针域置空*/ return L; } /*(1)---输出带头结点单链表的所有元素*/ void PrintList(LinkList L) { LinkList p = L->next; while(p){ printf("%d ",p->data); p = p->next; } }/*PrintList*/ /*(2)---在单链表的第i个位置插入元素e,若插入成功返回OK,插入失败返回ERROR*/ int InsertElem(LinkList L,int i,ElemType e) { LinkList p = L, s; int j=0; while(p && j< i-1 ){ p = p->next; j++; } if(!p || j>i-1) return ERROR; s = (LinkList)malloc(sizeof(LNode)); if(!s) return ERROR; s->data = e; s->next = p->next; p->next = s; return OK; }/* InsertElem */ /*(3)---查找第i位置的元素,若存在返回OK并由e返回其值,若不存在返回ERROR*/ int GetElem(LinkList L,int i,ElemType *e) { LinkList p = L; int j=0; while(p && j<i){ p = p->next; j++; } if(!p || j>i) return ERROR; *e = p->data; return OK; }/*GetElem*/ /*(4)---删除第i位置的元素,成功返回OK,并由e返回其值,若不成功返回ERROR,注意删除的结点必须释放其所占空间*/ int DeleteElem(LinkList L,int i,ElemType *e) { LinkList p = L, s; int j=0; while(p && j<i-1){ p = p->next; j++; } if(!p || j>i-1) return ERROR; s = p->next; p->next = s->next; *e = s->data; free(s); return OK; }/* DeleteElem */ /*(5)---创建具有n个结点的单链表,创建成功返回其头指针*/ LinkList CreateList(int n) { LinkList L = NULL, s; int e,i; L = InitList(L); for(i=0;i<n;i++){ printf("input e="); scanf("%d",&e); InsertElem(L,i+1,e); } return L; }/*CreateList*/ /*释放链表及其空间*/ void DestroyLinkList(LinkList L) { LNode *p=L,*q; while(p) { q=p->next; free(p); p=q; } }/* DestroyLinkList */
接下来提到了几个应用。
约瑟夫环
约瑟夫环是经典的循环链表的应用。用整数序列1,2,3,…,n表示顺序坐在圆桌周围的人,并采用循环链表作为存储结构。任意位置k开始计数,计到m让此位置的人出局,重复上述过程,直至只剩下最后一个人。依次输出每个出局的人的序号。
提示:用一个无头结点的循环单链表来实现n个元素的存储。exp2_3.c部分代码如下:
#include<stdio.h> #include<malloc.h> #define ERROR 0 #define OK 1 typedef int ElemType; /*定义表元素的类型*/ typedef struct LNode /*线性表的单链表存储*/ { ElemType data; struct LNode *next; } LNode,*LinkList; /*(1)---创建具有n个结点的无头结点的单向循环链表,返回其头指针*/ LinkList CreateList(int n) { int i; LinkList head = (LinkList)malloc(sizeof(struct LNode)); LinkList s=head,p; for(i=1;i<=n;i++) { p = (LinkList)malloc(sizeof(struct LNode)); p->data = i; s->next = p; s = p; } p->next = head->next; return head->next; }/*CreateList*/ /*(2)---输出无头结点循环单链表的所有元素*/ void PrintList(LinkList L) { LinkList p=L; while(p){ printf("%d ",p->data); p = p->next; } }/*PrintList*/ /*(3)---约瑟夫问题计算,依次输出出局的元素的序号*/ void JOSEPHUS(int n,int k,int m,LinkList L) { L = CreateList(n); int i; LinkList p = L,tmp; while(p->data!=k) p = p->next; while(p->next!=p) { for(i=0;i<m-1;i++) { tmp = p; p = p->next; } printf("%d ",p->data); tmp->next = p->next; free(p); p = tmp->next; } printf("%d",p->data); free(p); }/*JOSEPHUS*/ int main() { int n,m,k; LinkList L=NULL;/*定义指向单链表的指针*/ while(scanf("%d%d%d",&n,&k,&m)==3) /*n个元素从k位置开始每m个报数*/ JOSEPHUS(n,k,m,L); return 0; }
删除重复结点的链表
LinkList del(LinkList L) { LinkList p=L->next,q,r; while(p) { q = p; while(q->next) { if(q->next->data==p->data) { r = q->next; q->next = r->next; free(r); } else q = q->next; } p = p->next; } return L; }
相关文章推荐
- 使用httpclient提交数据
- java执行流程图
- 2015级C++第10、11周补充实践项目 继承和派生
- 使用反射生成并操作对象
- qt学习笔记(七)之数据库简介(所有支持数据库类型的列表)
- 冲刺第九天
- ajax
- 字符串匹配—KMP 扩展KMP Manacher
- Flask -- 使用数据库(Sqlite3)、用户注册、登录注销、修改密码
- 字串的连接最长路径查找(sort函数实现)
- 3牌递归
- SecureCRT 使用技巧
- Flyway学习笔记
- POJ 3461 Oulipo【kmp】
- 字典序法全排列
- sqoop学习
- [C语言][LeetCode][119]Pascal's Triangle II
- 学习计划(这是个队列,什么时候队列会为空?,学完,就删除)
- 站立会议09
- C#使用xpath查找xml节点信息