本程序实现了单链表的创建,结点的插入,删除,合并两个有序链表,求两个有序链表的交集,求两个有序链表的并集,求两个有序链表的差。
代码在VS2005编译下通过。有不当之处,不吝指教。QQ:381834158
// test2.cpp : 定义控制台应用程序的入口点。
//
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stdafx.h"
#include <stack>
#include <conio.h>
#include <iostream>
typedef struct node
{
int n;
struct node *NEXT;
int size;
}NODE;
void menu();
NODE* CreateNode();
bool InitNode(struct node *pnode);
struct node *MakeNewNode();
void PrintNode(struct node *pnode);
NODE *InsertNode(NODE *pn);
void ElementInsert(NODE *newNode,int &iLocation);
NODE *DeleteNode(NODE *pnode);
void ElementDelete(int& iLocation);
NODE* MergeList(NODE *pnode);
NODE *Union(NODE *pl1);
NODE *ListIntersection(NODE *pl);
NODE *DivList(NODE *pl1);
void main()
{
char ch=0;
NODE *head; //链表头结点
head = CreateNode();
menu();
while ((ch=getchar())!='q')
{
switch(ch)
{
case 'i':
InsertNode(head);
menu();
break;
case 'p':
PrintNode(head);
menu();
break;
case 'd':
DeleteNode(head);
menu();
break;
case 'm':
MergeList(head);
menu();
break;
case 'u':
Union(head);
menu();
case 's':
ListIntersection(head);
menu();
break;
case 'v':
DivList(head);
menu();
break;
default:
break;
}
}
}
void ElementDelete(int& iLocation)
{
puts("请输入要删除的元素的位置/n");
scanf("%d",&iLocation);
}
NODE *DeleteNode(NODE *pnode)
{
int p=1;
int iLocation=0;
NODE *head;
head=pnode;
NODE *q;
ElementDelete(iLocation);
while (pnode->NEXT&&p<iLocation-1)//前进到要删除结点的上一结点
{
p++;
pnode=pnode->NEXT;
}
if(iLocation==0||iLocation>head->size)
{
puts("删除位置不合理");
exit(0);
}
q=pnode->NEXT;
pnode->NEXT=q->NEXT;
head->size--;
free(q);
return head;
}
void menu()
{
puts(" i)插入 d)删除 m)归并链表 /n u)求两个有序链表的并集 s)求两个有序链表的交集 v)求两个有序链表的差集/n p)打印");
}
//
//从键盘获取要插入的位置和要插入的元素
//
void ElementInsert(NODE *newNode,int &iLocation)
{
puts("请输入结点元素(数字):/n");
scanf("%d",&newNode->n);
getchar();
puts("请输入插入的位置");
scanf("%d",&iLocation);
}
//
//在第n个位置之后插入元素
//
NODE *InsertNode(NODE *pn)
{
NODE *head;
head=pn;
int iLocation=0;
int p=1;
NODE *newNode;
newNode=MakeNewNode();
ElementInsert(newNode,iLocation);
while (pn&&p<iLocation) //前进到插入位置的前面那个结点
{
p++;
pn=pn->NEXT;
}
if(iLocation==0||iLocation>head->size)//插入到第一个元素之前或者插入位置大于全部元素个数时中止
{
puts("插入位置不合理");
exit(0);
}
newNode->NEXT=pn->NEXT;
pn->NEXT=newNode;
head->size++;
return head;
}
//
//打印全部结点
//
void PrintNode(struct node *pnode)
{
puts("结点信息:");
while (pnode!=NULL)
{
printf("%d ",pnode->n);
pnode=pnode->NEXT;//移动到下一个结点
}
puts("/n");
}
//
//创建指定个数的结点
//
NODE *CreateNode()
{
int n=0;
int number=0;
struct node *head,*pcurrent;
head=pcurrent=NULL;
puts("请输入要创建的结点个数/n");
scanf("%d",&n);
struct node *newNode;
for (int i=0;i<n;i++)
{
newNode = MakeNewNode();
InitNode(newNode);
puts("请输入结点元素(数字)");
scanf("%d",&number);
getchar();
newNode->n=number;
if (head==NULL)//如果是第一次创建结点,将新结点赋给头结点和当前结点
{
head=newNode;//头结点用来保存整个链表
pcurrent=newNode;
}
else //将新结点赋给当前结点
{
pcurrent->NEXT=newNode;
pcurrent=pcurrent->NEXT;
pcurrent->NEXT=NULL;
}
}
head->size=n;
return head;
}
//
//初始化结点
//
bool InitNode(struct node *pnode)
{
pnode->n=0;
pnode->NEXT=NULL;
return true;
}
//
//给新结点分配内存空间
//
struct node *MakeNewNode()
{
struct node *newNode;
newNode=(struct node*)malloc(sizeof(struct node));
if (newNode==NULL)
{
puts("末能分配结点内存!");
exit(1);
}
return newNode;
}
//
//有序链表合并,将有序链表pl1和pl2合并到pc
//
NODE* MergeList(NODE *pl1)
{
NODE *pc,*pcHead;
pc=MakeNewNode();
pcHead=MakeNewNode();
InitNode(pc);
InitNode(pcHead);
pcHead=pc;
NODE *pl2;
pl2 = CreateNode();
pc->size=0;
//pl1和pl2指向当前待比较插入的结点,pc指向表中最后一个结点.
//如果pl2->n<pl1-n,将pl2所指的结点链入pc结点之后,否则将pl1所指的结点链入pc之后
//当其中一个结点为空时跳出while循环
while (pl1&&pl2)
{
if (pl2->n<pl1->n)
{
pc->NEXT=pl2;
pc=pc->NEXT;
pl2=pl2->NEXT;
}
else
{
pc->NEXT=pl1;
pc=pc->NEXT;
pl1=pl1->NEXT;
}
pc->size++;
}
pc->NEXT=pl1?pl1:pl2;//将剩余段链入pc中
pc->size++;
return pcHead;
}
//
两个有序表求并集,将存在于表pl2和pl1中的元素并到表pc中
程序思路:依次比较两个有序链表结点指向的元素,将较小的元素所属结点链入新表后,
该结点前进到下一结点(如果相等,则两个表都前进到下一结点),直到两个表都为空表。
在表pl1或者表pl2不为空的前提条件下;
跟据判断,如果表pl1为空,将pl2指向的结点逐个链入到表pc中,如果表pl2为空,将表pl1指向的结点逐个链入表pc中;
如果两个表均不为空,而且结点元素相等,两个表都前进到下一个节点;
如果pl1指向的结点元素小于表pl12,将表pl1指向的结点复制到表pc中,然后表p1前进到下一个结点
否则,断定表pl2结点元素小于表pl1,因此将表pl2指向的结点复制到表pc中,然后前进到下一个结点
//
NODE *Union(NODE *pl1)
{
pl1->size=0;
NODE *pc,*pcHead,*pl2;
pc = MakeNewNode();
pcHead = MakeNewNode();
InitNode(pc);
InitNode(pcHead);
pl2 = CreateNode();
pcHead = pc;
while (pl1||pl2)
{
if (!pl1)//表pl1为空,则将pl2的结点赋给pc
{
pc->NEXT=pl2;
pc=pc->NEXT;
pl2=pl2->NEXT;//前进到下一个结点
}
else if (!pl2)
{
pc->NEXT=pl1;
pc=pc->NEXT;
pl1=pl1->NEXT;
}
else if (pl1->n==pl2->n)
{
pc->NEXT=pl1;
pc=pc->NEXT;
pl1=pl1->NEXT;
pl2=pl2->NEXT;
}
else if (pl1->n<pl2->n)
{
pc->NEXT=pl1;
pl1=pl1->NEXT;
pc=pc->NEXT;
}
else
{
pc->NEXT=pl2;
pl2=pl2->NEXT;
pc=pc->NEXT;
pl1->size++;
}
}
pc->NEXT=NULL;
return pcHead;
}
//
//求两个有序表的交集,将两个表中相同元素的结点链入到新表中
//
NODE *ListIntersection(NODE *pl1)
{
//程序思路,依次比较两个有序表中结点的元素,找到相等元素后将结点复制到新表。
//然后两个表中的结点都前进到下一结点。比较两个表中的结点,每次元素小的表结点都前进到下一个结点。直到任何一个结点到达表尾。
//在两个表均不为空的情况下,如果表pl1与表pl2结点中的元素相等,将表pl1结点复制到表pc中,
//两个结点前进到下一个结点,如果表pl1的元素小于表pl2结点中的元素,该结点前进到下一结点,否则表pl2的结点前时到下一个元素,直到其中一个表为空。
NODE *pc,*pcHead;
pc=MakeNewNode();
pcHead=MakeNewNode();
InitNode(pc);
InitNode(pcHead);
pcHead=pc;
NODE *pl2;
pl2 = CreateNode();
pc->size=0;
while(pl1&&pl2)
{
if (pl1->n==pl2->n)
{
pc->NEXT=pl2;
pc=pc->NEXT;
pl1=pl1->NEXT;
pl2=pl2->NEXT;
}
else if (pl1->n<pl2->n)
{
pl1=pl1->NEXT;
}
else
{
pl2=pl2->NEXT;
}
}
pc->NEXT=NULL;
return pcHead;
}
//
//求两个有序表的差集,将两个表中不同元素的结点链入到新表中
//
NODE *DivList(NODE *pl1)
{
pl1->size=0;
NODE *pc,*pcHead,*pl2;
pc = MakeNewNode();
pcHead = MakeNewNode();
InitNode(pc);
InitNode(pcHead);
pl2 = CreateNode();
pcHead = pc;
while (pl1 || pl2)
{
if (!pl1)
{
pc->NEXT=pl2;
pc=pc->NEXT;
pl2=pl2->NEXT;
}
else if (!pl2)
{
pc->NEXT=pl1;
pc=pc->NEXT;
pl2=pl2->NEXT;
}
else if (pl1->n==pl2->n)
{
pl1=pl1->NEXT;
pl2=pl2->NEXT;
}
else if (pl1->n<pl2->n)
{
pc->NEXT=pl1;
pc=pc->NEXT;
pl1=pl1->NEXT;
}
else
{
pc->NEXT=pl2;
pc=pc->NEXT;
pl2=pl2->NEXT;
}
}
pc->NEXT=NULL;
return pcHead;
}