数据结构-表的应用(单链表)

表的应用题

        顺序表即用简单数组实现的、用顺序存储结构保存的线性表,具有按元素序号随机访问的特点,方法简单,不用为表示结点间的逻辑关系而增加额外的存储开销。缺点是对较大的顺序表进行插入、删除操作时效率低下。
     链表由一系列不必在内存中相连的结构组成。链式存储结构不需要用地址连续的存储单元来实现,每个链式存储结构均含有表元素和一个链(link,指向包含该元素后续元素的结构的指针)。对链表的插入、删除操作不需要移动表元素和结构,因此效率较高,但增加了存储开销。

1.设有一个顺序表L(数据元素如:{1,1,2,3,5,8,13,13,21,34,34,55}),试编写一个算法函数,删除表中重复出现的数据元素。

#include <stdlib.h>
#include <stdio.h>
typedef int DataType;
#define ListSize 100 
typedef struct
{
    DataType items[ListSize];
    int length;
} orderList;
 
int initList(orderList *L);  
int ListLength(orderList L);  
int ListEmpty(orderList L);
int ListInsert(orderList *L, int pos, DataType item);
int ListDelete(orderList *L, int pos);
int TraverseList(orderList L);
int array_diff(orderList* L);
int main()
{
int test1_data[16] = {2,2,3,3,6,5,5,8,13,13,21,34,34,11,7,7};
	orderList L1;				
	initList(&L1); 					
	for (int k = 0; k < 16; k++)
	{
		
		if (!ListInsert(&L1, k +1, test1_data[k])) 
		{
			printf("插入失败\n");
			return 0;		
		}
	}

	printf("原序列:");
	TraverseList(L1); 
	array_diff(&L1);
	printf("去重后的序列:"); 
	TraverseList(L1);	
	return 0;
}

int initList(orderList *L) 
{
    L->length=0;
    return 1;
}

int ListLength(orderList L)  
{
    return L.length;
}

int ListEmpty(orderList L)   
{
    if(L.length<=0) return 1;
    else return 0;
}

int ListInsert(orderList *L, int pos, DataType item)  
{
    int i;
    
    if(L->length>=ListSize)
    {
        printf("顺序表已满,无法进行插入操作!");
        return 0;
    }
    if(pos<=0 || pos>L->length+1)
    {
        printf("插入位置不合法,取值范围应在[1,length+1]内");
        return 0;
    }
    for(i=L->length-1; i>=pos-1; i--)   
        L->items[i+1] = L->items[i];
    L->items[pos-1] = item;    
    L->length++;                
    return 1;
}

int ListDelete(orderList *L, int pos)     
{
    int i;
    if(ListEmpty(*L))
    {
        printf("顺序表为空表,无法进行删除操作!");
        return 0;
    }
    if(pos<1 || pos>L->length+1)
    {
        printf("删除位置不合法,取值范围因在[1,length+1]内");
        return 0;
    }
    for(i=pos; i<=L->length-1; i++)   
        L->items[i-1] = L->items[i];
    L->length--;         
    return 1;
}


int TraverseList(orderList L)          
{
    int i;
    for( i =0 ; i < L.length ; i++ ){
    	printf("%d ",L.items[i]);
	}
    printf("\n");
    return 1;
}

int array_diff(orderList* L)        
{ 
    for(int i=0; i<L->length; i++)
	{
	    int j=0;
		for(j=i+1; j<L->length; j++)
		{
			if(L->items[i]==L->items[j])
			{ 
				ListDelete(L, j);
				j=j-1;
			}
		}
	}
	return 0;
}

2.设有一个顺序表L(数据元素如:{1,-2,2,3,-5,-8,0,3,21,34,-55,77,-20,8,-2,3,13}),试编写一个算法,将L分拆为两个顺序表,使L中大于0的元素放在表LA中,其余元素放在LB中。

#include<stdio.h>
#include<stdlib.h>
/*定义单链表结构*/ 
typedef struct LNode                   
{
	int data;
	LNode *next;
}LNode, *LinkList;
 
/*创建链表*/ 
int CreateList(LinkList &L, int n){
	LNode *p, *r; int i;
	L = new LNode;
	L->next = NULL;
	r = L;
	for (i = 0; i<n; i++)
	{
		p = new LNode;
		scanf("%d",&p->data);
		p->next = NULL; r->next = p;  /*p指针的next指向NULL,r指针的next指向p*/ 
		r = p;
	}
	return 0;
}

/*输出链表函数*/ 
void display(LinkList L){
	LNode *p;
	p = L->next;
	printf("(");
	while (p)
	{
		printf("%d ",p->data);                  /*输出p指针所指向的data*/ 
		p = p->next;                          /*将p的next赋于p*/ 
	}
	printf(")\n");
}

/*分类链表函数代码*/ 
int SplitList_L(LinkList &L, LinkList &LA, LinkList &LB)    /*生成链表L,LA,LB*/ 
{
	LNode *p; LNode *pa; LNode *pb;     /*p,pa,pb分别为链表L,LA,LB的指针*/ 
	p = L->next; pa = LA; pb = LB;
	while (p)
	{
		if (p->data>0)                  /*指针p指向的data大于1,将data存入LA*/ 
		{
			pa->next = p;
			p = p->next;
			pa = pa->next;
			pa->next = NULL;
		}
		else                          /*指针p指向的data小于1,将data存入LB*/
		{
			pb->next = p;
			p = p->next;
			pb = pb->next;
			pb->next = NULL;
		}

	}
	return 0;

}

/*定义主函数*/ 
int main(){
	LinkList L; LinkList LA; LinkList LB; int n;
	printf("请输入链表L的长度:\n");
	scanf("%d",&n);
	printf("请输入数据\n");
	CreateList(L, n);

	printf("单链表L为:");
	display(L);

	LA = new LNode; LB = new LNode;
	LA->next = NULL; LB->next = NULL;

	SplitList_L(L, LA, LB);
	printf("分解后单链表A为:");
	display(LA);
	printf("分解后单链表B为:");
	display(LB);
	system("pause");
	return 0;
}

3.设有一个带头结点的单链表L(数据元素如:{1,1,2,3,5,8,13,13,21,34,34,55}),试编写一个算法函数,删除表中重复出现的元素。

#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct Lnode
{
	ElemType date;
	struct Lnode* next;
}*LNode;

LNode InitLnode(void)                 
{
	LNode L;
	L = (LNode)malloc(sizeof(struct Lnode));
	if(L == NULL)
		exit(1); 
	L->next = NULL;   	return L;
}
void Insert(LNode head,ElemType x);
void Print(LNode head);
void DeteleTheSame(LNode head);
int main(void)
{
	LNode head;
	head = InitLnode(); 
	ElemType n;
	printf("输入数据,0为结束\n");
	while(scanf("%d",&n)!=EOF)
	{
		if (n == 0) 
			break;
	Insert(head,n);
	}
	printf("当前数据为:\n");
	Print(head);
	printf("\n");
	DeteleTheSame(head);
	printf("删去重复数据后为:\n");
	Print(head);
	printf("\n");
	return 0;
}


void Insert(LNode head,ElemType x)
{
	struct Lnode *p,*q;
	p = head;
	q = (LNode)malloc(sizeof(struct Lnode));
	if(!q)
	{
		printf("Out of space\n");
		exit(1);
	}
	q->date = x;
	q->next = NULL;
	while(p->next != NULL)  
	{
		p = p->next;
	}
	p->next = q;
}

void Print(LNode head)
{
	LNode p;
	p = head->next;
	while(p!=NULL)
	{
		printf("%d ",p->date);
		p = p->next;
	}
}
void DeteleTheSame(LNode head)
{
	LNode p,q,t,s;
	p = head;
	p = p->next;          
	while(p!=NULL)
	{
		t = p;                        
		for(q = p->next;q != NULL;)
		{
			s = q;
			if(p->date == q->date)   
			{
				t->next = q->next;  
				q = q->next;         
				free(s);              
			}
			else                     
			{
				t = t->next;          
				q = q->next;       
			}
		}
		p = p->next;
	}
}
  1. 用单链表实现一元多项式的存储并实现两个多项式相加并输出结果,用单链表ha 存储多项式A(x)=a0+a1x1+a2x2+…+anxn(其中ai为非零系数),用单链表hb 存储多项式B(x)=b0+b1x1+b2x2+…+bmxm(其中bj为非零系数),要求计算C(x)= A(x)+B(x),结果存到单链表hc中。
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct node
{
	double coef;
	int exp;
}polyarray[MAX];
typedef struct polynode
{
	double coef;
	int exp;
	struct polynode *next;
}polynode;
 
void create(polynode *&L,polyarray a,int n);
void show(polynode *L); 
void destroy(polynode *&L);
void sort(polynode *head);
void add(polynode *ha,polynode *hb,polynode *&hc);

void show(polynode *L)
{
	int first=1;
	polynode *p=L->next;
	while(p!=NULL)
	{
		if(first)
			first=0;
		else if(p->coef>0)
			printf("+");
		if(p->exp==0)
			printf("%g",p->coef);
		else if(p->exp==1)
			printf("%gx",p->coef);
		else
			printf("%gx^%d",p->coef,p->exp);
		p=p->next;
	}
	printf("\n");
}
void destroy(polynode *&L)
{
	polynode *p=L,*q=p->next;
	while(q!=NULL)
	{
		free(p);
		p=q;
		q=p->next;
	}
	free(p);
}
void create(polynode *&L,polyarray a,int n)
{
	polynode *s,*r;
	int i;
	L=(polynode *)malloc(sizeof(polynode));
	L->next=NULL;
	r=L;
	for(i=0;i<n;i++)
	{
		s=(polynode *)malloc(sizeof(polynode));
		s->coef=a[i].coef; 
		s->exp=a[i].exp; 
		r->next=s;
		r=s;
	}
	r->next=NULL;
}
void sort(polynode *head)
{
	polynode *p=head->next,*q,*r;
	if(p!=NULL)
	{
		r=p->next;
		p->next=NULL;
		p=r; 
		while(p!=NULL)
		{
			r=p->next;
			q=head;
			while(q->next!=NULL&&q->next->exp>p->exp)
				q=q->next;
			p->next=q->next;
			q->next=p;
			p=r;
		}
	}
}
void add(polynode *ha,polynode *hb,polynode *&hc)
{
	double c;
	polynode *pa=ha->next,*pb=hb->next,*s,*tc;
	hc=(polynode *)malloc(sizeof(polynode));
	tc=hc;
	while(pa!=NULL&&pb!=NULL)
	{
		if(pa->exp>pb->exp)
		{
			s=(polynode *)malloc(sizeof(polynode));
			s->exp=pa->exp;s->coef=pa->coef;
			tc->next=s;tc=s;
			pa=pa->next;
		}
		else if(pa->exp<pb->exp) 
		{
			s=(polynode *)malloc(sizeof(polynode));
			s->exp=pb->exp;s->coef=pb->coef;
			tc->next=s;tc=s;
			pb=pb->next;
		}
		else
		{
			c=pa->coef+pb->coef;
			if(c!=0)
			{
				s=(polynode *)malloc(sizeof(polynode));
				s->exp=pa->exp;s->coef=c;
			    tc->next=s;tc=s;
			}
			pa=pa->next;
			pb=pb->next;
		}
	}
	if(pb!=NULL)pa=pb;
	while(pa!=NULL)
	{
		s=(polynode *)malloc(sizeof(polynode));
		s->exp=pa->exp;s->coef=pa->coef;
		tc->next=s;tc=s;
		pa=pa->next;
	}
	tc->next=NULL;
}
int main()
{
	polynode *ha,*hb,*hc;
	polyarray a={{1,6},{1,2},{1,3},{-10,6}};
	polyarray b={{1,1},{-4,2},{3,4},{9,10},{1,20}};
	create(ha,a,4);
	create(hb,b,5);
	printf("原多项式A:  ");show(ha);
	printf("原多项式B:  ");show(hb);
	sort(ha);
	sort(hb);
	printf("有序多项式A:  ");show(ha);
	printf("有序多项式B:  ");show(hb);
	add(ha,hb,hc);
	printf("多项式相加:  ");show(hc);
	destroy(ha);
	destroy(hb);
	destroy(hc);
	return 0;
}
  1. 约瑟夫(Josephus)环问题:设有n个人围坐在一个圆桌周围,现从第s个人开始报数,报数到m时,第m个人出列,然后从第m+1个人开始重新报数,报数到m时,第m个人又出列,如此反复,知道所有人全部出列为止。对于任意给定的n、s和m,求出按出列次序得到的n个人的序列。
    提示:例如n=8,s=1,m=4为例,人员编号为n1、n2、n3、n4、n5、n6、n7、n8,出列次序为:n4、n8、n5、n2、n1、n3、n7、n6。
    要求: 1)采用顺序表模拟解决;
    2)采用循环链表模拟解决。
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
    int number;
    struct node * next;
}person;
person * initLink(int n){
    person * head=(person*)malloc(sizeof(person));
    head->number=1;
    head->next=NULL;
    person * cyclic=head;
    for (int i=2; i<=n; i++) {
        person * body=(person*)malloc(sizeof(person));
        body->number=i;
        body->next=NULL; 
        cyclic->next=body;
        cyclic=cyclic->next;
    }
    cyclic->next=head;//首尾相连
    return head;
}
void findAndKillK(person * head,int k,int m){
    person * tail=head;
    //找到链表第一个结点的上一个结点,为删除操作做准备
    while (tail->next!=head) {
        tail=tail->next;
    }
    person * p=head;
    //找到编号为k的人
    while (p->number!=k) {
        tail=p;
        p=p->next;
    }
    //从编号为k的人开始,只有符合p->next==p时,说明链表中除了p结点,所有编号都出列了,
    while (p->next!=p) {
        //找到从p报数1开始,报m的人,并且还要知道数m-1de人的位置tail,方便做删除操作。
        for (int i=1; i<m; i++) {
            tail=p;
            p=p->next;
        }
        tail->next=p->next;//从链表上将p结点摘下来
        printf("出列人的编号为:%d\n",p->number);
        free(p);
        p=tail->next;//继续使用p指针指向出列编号的下一个编号,游戏继续
    }
    printf("出列人的编号为:%d\n",p->number);
    free(p);
}
int main() {
    printf("输入圆桌上的人数n:");
    int n;
    scanf("%d",&n);
    person * head=initLink(n);
    printf("从第k人开始报数(k>1且k<%d):",n);
    int k;
    scanf("%d",&k);
    printf("数到m的人出列:");
    int m;
    scanf("%d",&m);
    findAndKillK(head, k, m);
    return 0;
}

支持可以关注我哦,持续分享编写的代码。

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火球2号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值