您的位置:首页 > 其它

链表操作

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: