已知A,B,C为三个元素值递增有序的线性表,要求对表A如下运算:删去那些既在表B中出现又在表C
这个是单链表的,顺序表我也有写,在我的另一个文章中
我不太善于解释,注释都写在代码旁边了,function里面的算法就是作业要求的,直接看就可以了,不过整体看过来可能更好,希望能帮到你吧
#include
#include
#include
#define Elemtype int
typedef struct SList
{Elemtype data;struct SList *next;
}Node;void initial(Node **head);
void push_back(Node *head,Elemtype x);
void show(Node *head);
Node* _buynode(Elemtype x);
void function(Node *ha,Node *hb,Node *hc);int main()
{Node *ha,*hb,*hc;initial(&ha);initial(&hb);initial(&hc);printf("创建单链表A(-1结束)\n");int x;while(1){scanf("%d",&x);if(x==-1)break;push_back(ha,x);}printf("这是单链表a>>> \n");show(ha);printf("创建单链表B(-1结束)\n");while(1){scanf("%d",&x);if(x==-1)break;push_back(hb,x);}printf("这是单链表b>>> \n");show(hb);printf("创建单链表C(-1结束)\n");while(1){scanf("%d",&x);if(x==-1)break;push_back(hc,x);}printf("这是单链表c>>> \n");show(hc);printf("function过后的单链表a>>>");function(ha,hb,hc);show(ha);return(1);
}Node* _buynode(Elemtype x)
{//本算法的功能是申请一个节点,数据域存放x,并且返回该节点的指针Node *s=(Node*)malloc(sizeof(Node));assert(s!=NULL);s->data=x;//数据域赋值xs->next=NULL;return(s);//返回该节点
}void initial(Node **head)
{//本算法的功能是初始化一个头指针,使其指向一个头结点(*head)=(Node*)malloc(sizeof(Node));assert((*head)!=NULL);(*head)->data=0;//空表(*head)->next=NULL;
}void push_back(Node *head,Elemtype x)
{//本算法的前提是单链表已经初始化//本算法的功能是在单链表的尾部插入一个新的节点,节点的数据域//赋值为xNode *s=_buynode(x);Node *p=head;while(p->next!=NULL)p=p->next;//p指向单链表的尾部节点s->next=p->next;p->next=s;head->data++;//表长加一
}void show(Node *head)
{//本算法的前提是链表已经初始化并且不空//本算法的功能是依次显示单链表中的元素if(head->data==0)return;//表长合法性判断Node *p=head;while(p->next!=NULL){printf("%d-->",p->next->data);p=p->next;}printf("Null.\n");
}void function(Node *ha,Node *hb,Node *hc)
{//本算法的前提是三个表都不能为空//本算法的功能是除去表a中在表b和表c同时出现的元素if(ha->data==0 || hb->data==0 || hc->data==0)return;//表长合法性判断Node *pa,*pb,*pc;pa=ha;pb=hb->next;pc=hc->next;while(pa->next && pb && pc)//当pa节点下一个不空,pb,pc不空{while(pb!=NULL && pc!=NULL && pb->data!=pc->data)//移动pb,pc直到相同{if(pb->data<pc->data)//如果pb的小,则移动pbpb=pb->next;elsepc=pc->next;}if(pb!=NULL && pc!=NULL)//b表和c表中有相同的元素{while(pb->next!=NULL&&pb->data==pb->next->data || pc->next!=NULL&&pc->data==pc->next->data)//使pa和pb移向重复元素中的最后一个元素{if(pb->next!=NULL && pb->data==pb->next->data)pb=pb->next;if(pc->next!=NULL && pc->data==pc->next->data)pc=pc->next;}while(pa->next!=NULL && pa->next->data<pb->data){pa=pa->next;}if(pa->next!=NULL && pa->next->data==pb->data){while(pa->next!=NULL && pa->next->data==pb->data)//删除重复的元素{Node *q=pa->next;pa->next=q->next;free(q);ha->data--;//表长减一}pb=pb->next;pc=pc->next;//pa pb同时移动到下一个节点}}}
}
运行结果:
创建单链表A(-1结束)
1 2 3 4 5 6 7 -1
这是单链表a>>>
1–>2–>3–>4–>5–>6–>7–>Null.
创建单链表B(-1结束)
1 3 5 7 10 11 -1
这是单链表b>>>
1–>3–>5–>7–>10–>11–>Null.
创建单链表C(-1结束)
1 5 6 7 10 11 -1
这是单链表c>>>
1–>5–>6–>7-->10–>11–>Null.
function过后的单链表a>>>2–>3–>4–>6–>Null.
整个算法的核心就在一个while循环里面了,也怪我追求简洁的代码,其实可以分解为两个算法,一个是先求B∩C=D,然后再运算A-D,就得到想要的A单链表了。
while循环蛮长的,条件蛮多的,其实考虑得挺仔细的,方方面面都要考虑到,但是只要读一次while循环就可以了,下一个while循环是同样的步骤(好像在说废话),有一个读懂过程复杂代码的好方法,就是自己举一个例子,最好是特殊情况多的,然后跟着程序跑,就理解了,如果能优化,麻烦在评论区告诉我哦,谢谢~
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
