一二章算法数据结构李葆春一二章算法word版.docx
《一二章算法数据结构李葆春一二章算法word版.docx》由会员分享,可在线阅读,更多相关《一二章算法数据结构李葆春一二章算法word版.docx(30页珍藏版)》请在冰豆网上搜索。
一二章算法数据结构李葆春一二章算法word版
//一,二章算法
//说明
//sqlist——顺序表linklist——单链表dlinklist——双链表
//clinklist——循环单链表cdlinklist——循环双链表
//目录
//算法1:
求一元二次方程的根()
//算法2:
在顺序表L中删除所有值为x的元素(sqlist.cpp)
//算法3:
将整数顺序表L以第一个元素为分界线(基准)进行划分(sqlist.cpp)
//算法4:
将整数顺序表L中所有奇数移动到偶数的前面(sqlist.cpp)
//算法5:
单链表L拆分成两个单链表(linklist.cpp)
//算法6:
删除单链表L中最大元素的结点(linklist.cpp)
//算法7:
单链表L递增排序(linklist.cpp)
//算法8:
双链表所有结点逆置(dlinklist.cpp)
//算法9:
双链表递增排序(dlinklist.cpp)
//算法10:
统计循环单链表L中值为x的结点个数。
(clinklist.cpp)
//算法11:
在循环双链表L中删除第一个值为x的结点。
(cdlinklist.cpp)
//算法12:
判断循环双链表L中的数据结点是否对称。
(cdlinklist.cpp)
//算法13,二路归并:
采用顺序表实现(sqlist.cpp)
//算法14,二路归并:
采用单链表实现(linklist.cpp)
//算法15:
求3个有序单链表的公共结点(linklist.cpp)
//算法16:
高效删除有序单链表的值重复结点(linklist.cpp)
//算法17:
求两个等长的有序顺序表的中位数。
(sqlist.cpp)
//算法18:
两个表的简单自然连接的算法()
//算法
//算法1:
求一元二次方程的根
#include
#include
intsolution(doublea,doubleb,doublec,double&x1,double&x2)
{
doubled;
d=b*b-4*a*c;
if(d>0)
{
x1=(-b+sqrt(d))/(2*a);
x2=(-b-sqrt(d))/(2*a);
return2;//2个实根
}
elseif(d==0)
{
x1=(-b)/(2*a);
return1;//1个实根
}
else//d<0的情况
return0;//不存在实根
}
intmain()
{
doublea=2,b=-6,c=3;
doublex1,x2;
ints=solution(a,b,c,x1,x2);
if(s==1)
printf("一个根:
x=%lf\n",x1);
elseif(s==2)
printf("两个根:
x1=%lf,x2=%lf\n",x1,x2);
else
printf("没有根\n");
return1;
}
//算法2:
在顺序表L中删除所有值为x的元素
#include"sqlist.cpp"
voiddelnode1(SqList*&L,ElemTypex)
{
intk=0,i;//k记录值不等于x的元素个数
for(i=0;ilength;i++)
if(L->data[i]!
=x)
{
L->data[k]=L->data[i];
k++;//不等于x的元素增1
}
L->length=k;//顺序表L的长度等于k
}
voiddelnode2(SqList*&L,ElemTypex)
{
intk=0,i=0;//k记录值等于x的元素个数
while(ilength)
{
if(L->data[i]==x)
k++;
else
L->data[i-k]=L->data[i];//当前元素前移k个位置
i++;
}
L->length-=k;//顺序表L的长度递减k
}
intmain()
{
ElemTypea[]={1,2,2,1,0,2,4,2,3,1};
ElemTypex=2;
SqList*L;
CreateList(L,a,10);
printf("L:
");DispList(L);
printf("删除值为%d的元素\n",x);
delnode2(L,x);
printf("L:
");DispList(L);
DestroyList(L);
return1;
}
//算法3:
将整数顺序表L以第一个元素为分界线(基准)进行划分
#include"sqlist.cpp"
voidswap(int&x,int&y)//交换x和y
{inttmp=x;
x=y;y=tmp;
}
voidmove1(SqList*&L)
{inti=0,j=L->length-1;
ElemTypepivot=L->data[0];//以data[0]为基准
while(i{while(idata[j]>pivot)
j--;//从右向左扫描,找一个小于等于pivot的元素
while(idata[i]<=pivot)
i++;//从左向右扫描,找一个大于pivot的元素
if(iswap(L->data[i],L->data[j]);//将L->data[i]和L->data[j]进行交换
}
swap(L->data[0],L->data[i]);//将L->data[0]和L->data[i]进行交换
}
voidmove2(SqList*&L)
{inti=0,j=L->length-1;
ElemTypepivot=L->data[0];//以data[0]为基准
while(i{while(j>i&&L->data[j]>pivot)
j--;//从右向左扫描,找一个小于等于pivot的data[j]
L->data[i]=L->data[j];//找到这样的data[j],放入data[i]处
while(idata[i]<=pivot)
i++;//从左向右扫描,找一个大于pivot的记录data[i]
L->data[j]=L->data[i];//找到这样的data[i],放入data[j]处
}
L->data[i]=pivot;
printf("i=%d\n",i);
}
intmain()
{
SqList*L;
ElemTypea[]={1,9,8,7,6};
CreateList(L,a,5);
printf("L:
");DispList(L);
printf("执行移动运算\n");
move1(L);
printf("L:
");DispList(L);
DestroyList(L);
return1;
}
//算法4:
将整数顺序表L中所有奇数移动到偶数的前面
#include"sqlist.cpp"
voidswap(int&x,int&y)//交换x和y
{inttmp=x;
x=y;y=tmp;
}
voidmove1(SqList*&L)
{
inti=0,j=L->length-1;
while(i{
while(idata[j]%2==0)
j--;//从右向左扫描,找一个奇数元素
while(idata[i]%2==1)
i++;//从左向右扫描,找一个偶数元素
if(idata[i]和L->data[j]交换
swap(L->data[i],L->data[j]);
}
}
voidmove2(SqList*&L)
{inti=-1,j;
for(j=0;j<=L->length-1;j++)
if(L->data[j]%2==1)//j指向奇数时
{
i++;//奇数区间个数增1
if(i!
=j)//若i、j不相等
swap(L->data[i],L->data[j]);//L->data[i]和L->data[j]交换
}
}
intmain()
{
SqList*L;
ElemTypea[]={8,2,7,1,5,10,4,6,3,9};
CreateList(L,a,10);
printf("L:
");DispList(L);
printf("执行移动运算\n");
move1(L);
printf("L:
");DispList(L);
DestroyList(L);
return1;
}
//算法5:
单链表L拆分成两个单链表
#include"linklist.cpp"
voidsplit(LinkNode*&L,LinkNode*&L1,LinkNode*&L2)
{LinkNode*p=L->next,*q,*r1;//p指向第1个数据结点
L1=L;//L1利用原来L的头结点
r1=L1;//r1始终指向L1的尾结点
L2=(LinkNode*)malloc(sizeof(LinkNode));//创建L2的头结点
L2->next=NULL;//置L2的指针域为NULL
while(p!
=NULL)
{r1->next=p;//采用尾插法将结点p(data值为ai)插入L1中
r1=p;
p=p->next;//p移向下一个结点(data值为bi)
q=p->next;//由于头插法修改p的next域,故用q保存结点p的后继结点
p->next=L2->next;//采用头插法将结点p插入L2中
L2->next=p;
p=q;//p重新指向ai+1的结点
}
r1->next=NULL;//尾结点next置空
}
intmain()
{
LinkNode*L,*L1,*L2;
intn=10;
ElemTypea[]={1,2,3,4,5,6,7,8,9,10};
InitList(L);
InitList(L1);
InitList(L2);
CreateListR(L,a,n);
printf("L:
");DispList(L);
printf("L->L1,L2\n");
split(L,L1,L2);
printf("L1:
");DispList(L1);
printf("L2:
");DispList(L2);
DestroyList(L1);
DestroyList(L2);
return1;
}
//算法6:
删除单链表L中最大元素的结点
#include"linklist.cpp"
voiddelmaxnode(LinkNode*&L)
{
LinkNode*p=L->next,*pre=L,*maxp=p,*maxpre=pre;
while(p!
=NULL)//用p扫描整个单链表,pre始终指向其前驱结点
{
if(maxp->datadata)//若找到一个更大的结点
{maxp=p;//更改maxp
maxpre=pre;//更改maxpre
}
pre=p;//p、pre同步后移一个结点
p=p->next;
}
maxpre->next=maxp->next;//删除maxp结点
free(maxp);//释放maxp结点
}
intmain()
{
LinkNode*L;
intn=10;
ElemTypea[]={1,3,2,9,0,4,7,6,5,8};
CreateListR(L,a,n);
printf("L:
");DispList(L);
printf("删除最大值结点\n");
delmaxnode(L);
printf("L:
");DispList(L);
DestroyList(L);
return1;
}
//算法7:
单链表L递增排序
#include"linklist.cpp"
voidsort(LinkNode*&L)
{
LinkNode*p,*pre,*q;
p=L->next->next;//p指向L的第2个数据结点
L->next->next=NULL;//构造只含一个数据结点的有序表
while(p!
=NULL)
{
q=p->next;//q保存p结点后继结点的指针
pre=L;//从有序表开头进行比较,pre指向p结点的前驱结点
while(pre->next!
=NULL&&pre->next->datadata)
pre=pre->next;//在有序表中找插入p结点的前驱结点pre
p->next=pre->next;//在pre结点之后插入p结点
pre->next=p;
p=q;//扫描原单链表余下的结点
}
}
intmain()
{
LinkNode*L;
intn=10;
ElemTypea[]={1,3,2,9,0,4,7,6,5,8};
CreateListR(L,a,n);
printf("L:
");DispList(L);
printf("排序\n");
sort(L);
printf("L:
");DispList(L);
DestroyList(L);
return1;
}
//算法8:
双链表所有结点逆置
#include"dlinklist.cpp"
voidreverse(DLinkNode*&L)//双链表结点逆置
{
DLinkNode*p=L->next,*q;//p指向开好结点
L->next=NULL;//构造只有头结点的双链表L
while(p!
=NULL)//扫描L的数据结点
{
q=p->next;//因头插法会修改p结点的next域,用q保存其后继结点
p->next=L->next;//采用头插法将p结点插入到双链表中
if(L->next!
=NULL)//若L中存在数据结点,修改其前驱指针
L->next->prior=p;
L->next=p;
p->prior=L;
p=q;//让p重新指向其后继结点
}
}
intmain()
{
ElemTypea[]={1,8,0,4,9,7,5,2,3,6};
DLinkNode*L;
CreateListR(L,a,10);
printf("L:
");DispList(L);
printf("逆置\n");
reverse(L);
printf("L:
");DispList(L);
DestroyList(L);
return1;
}
//算法9:
双链表递增排序
#include"dlinklist.cpp"
voidsort(DLinkNode*&L)
{
DLinkNode*p,*pre,*q;
p=L->next->next;//p指向L的第2个数据结点
L->next->next=NULL;//构造只含一个数据结点的有序表
while(p!
=NULL)
{
q=p->next;//q保存p结点后继结点的指针
pre=L;//从有序表开头进行比较,pre指向p结点的前驱结点
while(pre->next!
=NULL&&pre->next->datadata)
pre=pre->next;//在有序表中找插入p结点的前驱结点pre
p->next=pre->next;//在pre结点之后插入到p结点
if(pre->next!
=NULL)
pre->next->prior=p;
pre->next=p;
p->prior=pre;
p=q;//扫描原双链表余下的结点
}
}
intmain()
{
ElemTypea[]={1,8,0,4,9,7,5,2,3,6};
DLinkNode*L;
CreateListR(L,a,10);
printf("L:
");DispList(L);
printf("排序\n");
sort(L);
printf("L:
");DispList(L);
DestroyList(L);
return1;
}
//算法10:
统计循环单链表L中值为x的结点个数。
#include"clinklist.cpp"
intcount(LinkNode*L,ElemTypex)
{
intn=0;
LinkNode*p=L->next;//指向第1个数据结点
while(p!
=L)
{
if(p->data==x)n++;
p=p->next;
}
return(n);
}
intmain()
{
ElemTypea[]={1,2,2,4,2,3,5,2,1,4};
ElemTypex=2;
LinkNode*L;
CreateListR(L,a,10);
printf("L:
");DispList(L);
printf("结点值为%d的结点个数:
%d\n",x,count(L,x));
DestroyList(L);
return1;
}
//算法11:
在循环双链表L中删除第一个值为x的结点。
#include"cdlinklist.cpp"
booldelelem(DLinkNode*&L,ElemTypex)
{
DLinkNode*p=L->next;
while(p!
=L&&p->data!
=x)
p=p->next;
if(p!
=L)//找到第一个元素值为x的结点
{
p->next->prior=p->prior;//删除结点*p
p->prior->next=p->next;
free(p);
returntrue;
}
else
returnfalse;
}
intmain()
{
ElemTypea[]={1,2,2,4,2,3,5,2,1,4};
ElemTypex=1;
DLinkNode*L;
CreateListR(L,a,10);
printf("L:
");DispList(L);
printf("删除第一个结点值为%d的结点\n",x);
if(delelem(L,x))
{
printf("L:
");DispList(L);
}
else
printf("循环双链表L中不存在元素值为%d的结点\n",x);
DestroyList(L);
return1;
}
//算法12:
判断循环双链表L中的数据结点是否对称。
#include"cdlinklist.cpp"
boolSymm(DLinkNode*L)
{
boolsame=true;//same表示L是否对称,初始时为真
DLinkNode*p=L->next;//p指向首结点
DLinkNode*q=L->prior;//q指向尾结点
while(same)
{
if(p->data!
=q->data)//对应结点值不相同,退出循环
same=false;
else
{
if(p==q||p==q->prior)break;
q=q->prior;//q前移一个结点
p=p->next;//p后移一个结点
}
}
returnsame;
}
intmain()
{
ElemTypea[]={1,2,3,2,1};
intn=5;
DLinkNode*L;
CreateListR(L,a,n);
printf("L:
");DispList(L);
if(Symm(L))
printf("L是对称的\n");
else
printf("L是不对称的\n");
DestroyList(L);
return1;
}
//算法13,二路归并:
采用顺序表实现
#include"sqlist.cpp"
voidUnionList(SqList*LA,SqList*LB,SqList*&LC)
{
inti=0,j=0,k=0;//i、j、k分别作为LA、LB、LC的下标
LC=(SqList*)malloc(sizeof(SqList));
LC->length=0;
while(ilength&&jlength)
{
if(LA->data[i]data[j])
{
LC->data[k]=LA->data[i];
i++;k++;
}
else//LA->data[i]>LB->data[j]
{
LC->data[k]=LB->data[j];
j++;k++;
}