数据结构学习笔记.docx

上传人:b****5 文档编号:12334279 上传时间:2023-04-18 格式:DOCX 页数:39 大小:347.58KB
下载 相关 举报
数据结构学习笔记.docx_第1页
第1页 / 共39页
数据结构学习笔记.docx_第2页
第2页 / 共39页
数据结构学习笔记.docx_第3页
第3页 / 共39页
数据结构学习笔记.docx_第4页
第4页 / 共39页
数据结构学习笔记.docx_第5页
第5页 / 共39页
点击查看更多>>
下载资源
资源描述

数据结构学习笔记.docx

《数据结构学习笔记.docx》由会员分享,可在线阅读,更多相关《数据结构学习笔记.docx(39页珍藏版)》请在冰豆网上搜索。

数据结构学习笔记.docx

数据结构学习笔记

一、数据结构算法实现

1、排序算法集锦

1、直接插入排序:

代码:

//插入排序。

//时间复杂度:

O(n)。

空间复杂度:

O

(1)。

为稳定排序。

#include

#include

voidInsertSort(inta[],intn){//对顺序表做直接插入排序。

intj,k;

for(j=2;j<=n;j++)

if(a[j]

a[0]=a[j];//复制为哨兵。

a[j]=a[j-1];

for(k=j-2;a[0]

a[k+1]=a[k];//记录后移。

a[k+1]=a[0];//插入到正确位置。

}

}

intmain(){

inta[100],n,i;

printf("请输入要进行排序的数的个数n:

\n");

scanf("%d",&n);

printf("请输入这n个数:

\n");

for(i=1;i<=n;i++)

scanf("%d",&a[i]);

InsertSort(a,n);

printf("排序后的n个数是:

\n");

for(i=1;i<=n;i++)

printf("%4d",a[i]);

printf("\n");

system("pause");

}

数据测试:

2、折半插入排序

代码:

//折半插入排序。

//时间复杂度:

O(n)。

空间复杂度:

O

(1);

#include

#include

voidBInsertSort(inta[],intn){//对顺序表做折半插入排序。

intj,k;

for(j=2;j

a[0]=a[j];

intlow=1,high=j-1;

while(low<=high){//在a[low..high]中折半查找正确插入位置。

intm=(low+high)/2;

if(a[0]

elselow=m+1;

}

for(k=j-1;k>=high+1;k--)//记录后移。

a[k+1]=a[k];

a[high+1]=a[0];//插入。

}

}

intmain(){

inta[100],n,i;

printf("请输入要进行排序的数的个数n:

\n");

scanf("%d",&n);

printf("请输入这n个数:

\n");

for(i=1;i<=n;i++)

scanf("%d",&a[i]);

BInsertSort(a,n);

printf("排序后的n个数是:

\n");

for(i=1;i<=n;i++)

printf("%4d",a[i]);

printf("\n");

system("pause");

}

数据测试:

3、希尔排序:

代码:

//希尔排序。

//时间复杂度:

O(nlogn)。

空间复杂度:

O

(1)。

为不稳定算法。

#include

#include

voidShellInsert(inta[],intn,intdk){//对顺序表a[]做一趟希尔插入排序。

intj,k;

for(j=dk+1;j<=n;j++)

if(a[j]

a[0]=a[j];

for(k=j-dk;k>0&&a[0]

a[k+dk]=a[k];

a[k+dk]=a[0];

}

}

voidShellSort(inta[],intn,intdlta[],intt){//按增量序列dlta[]对顺序表做希尔排序。

intm;

for(m=0;m

ShellInsert(a,n,dlta[m]);

}

intmain(){

inta[100],dlta[20],n,t,i;

printf("请输入要进行排序的数的个数n:

\n");

scanf("%d",&n);

printf("请输入这n个数:

\n");

for(i=1;i<=n;i++)

scanf("%d",&a[i]);

printf("请输入增量序列数的个数t:

\n");

scanf("%d",&t);

printf("请输入增量序列:

\n");

for(i=0;i

scanf("%d",&dlta[i]);

ShellSort(a,n,dlta,t);

printf("排序后的n个数是:

\n");

for(i=1;i<=n;i++)

printf("%4d",a[i]);

printf("\n");

system("pause");

}

数据测试:

4、冒泡排序

代码:

//起泡排序。

//时间复杂度:

O(n^2)。

空间复杂度:

O

(1)。

为稳定排序算法。

#include

#include

voidBubbleSort(inta[],intn){

inti,j,temp;

for(i=1;i<=n-1;i++){

for(j=1;j<=n-i;j++){

if(a[j]>a[j+1]){

temp=a[j];

a[j]=a[j+1];

a[j+1]=temp;

}

}

}

}

intmain(){

inta[100],n,i;

printf("请输入要进行排序的数的个数n:

\n");

scanf("%d",&n);

printf("请输入这n个数:

\n");

for(i=1;i<=n;i++)//注意数组的起始位置。

scanf("%d",&a[i]);

BubbleSort(a,n);

printf("排序后的n个数是:

\n");

for(i=1;i<=n;i++)

printf("%4d",a[i]);

printf("\n");

system("pause");

}

数据测试:

5、快速排序:

代码:

//快速排序。

//时间复杂度:

O(nlogn)。

空间复杂度:

O(logn)。

为不稳定算法。

#include

#include

intPartition(inta[],intn,intlow,inthigh){//返回枢轴所在位置。

intpivotkey;

a[0]=a[low];

pivotkey=a[low];

while(low

while(lowpivotkey)high--;

a[low]=a[high];

while(low

a[high]=a[low];

}

a[low]=a[0];

returnlow;

}

voidQuickSort(inta[],intn,intlow,inthigh){//递归形式快排。

intpivotloc;

if(low

pivotloc=Partition(a,n,low,high);

QuickSort(a,n,low,pivotloc-1);

QuickSort(a,n,pivotloc+1,high);

}

}

intmain(){

inta[100],n,i;

printf("请输入要进行排序的数的个数n:

\n");

scanf("%d",&n);

printf("请输入这n个数:

\n");

for(i=1;i<=n;i++)//注意数组的起始位置。

scanf("%d",&a[i]);

QuickSort(a,n,1,n);

printf("排序后的n个数是:

\n");

for(i=1;i<=n;i++)

printf("%4d",a[i]);

printf("\n");

system("pause");

}

数据测试:

6、简单选择排序

代码:

//简单选择排序。

//时间复杂度:

O(n^2)。

空间复杂度:

O

(1)

#include

#include

intSelectMinKey(inta[],intn,inti){

intj,min;

min=i;

for(j=i+1;j<=n;j++){

if(a[j]

min=j;

}

returnmin;

}

voidSelectSort(inta[],intn){

inti,j,temp;

for(i=1;i

j=SelectMinKey(a,n,i);

if(i!

=j){

temp=a[i];

a[i]=a[j];

a[j]=temp;

}

}

}

intmain(){

inta[100],n,i;

printf("请输入要进行排序的数的个数n:

\n");

scanf("%d",&n);

printf("请输入这n个数:

\n");

for(i=1;i<=n;i++)//注意数组的起始位置。

scanf("%d",&a[i]);

SelectSort(a,n);

printf("排序后的n个数是:

\n");

for(i=1;i<=n;i++)

printf("%4d",a[i]);

printf("\n");

system("pause");

}

数据测试:

7、堆排序

代码;

数据测试:

8、归并排序

代码:

//归并排序。

//时间复杂度:

O(nlogn)。

空间复杂度:

O(n)。

#include

#include

voidMerge(intSR[],intTR[],intn,inti,intm,intt){

//将有序的a[i..m]和a[m+1..t]合并为有序的TR[i..t]。

intj,k;

for(j=m+1,k=i;i<=m&&j<=t;k++){

if(SR[i]<=SR[j])TR[k]=SR[i++];

elseTR[k]=SR[j++];

}

if(i<=m)

while(i<=m)

TR[k++]=SR[i++];

if(j<=t)

while(j<=t)

TR[k++]=SR[j++];

}

voidMSort(intSR[],intTR[],intn,ints,intt){

//将SR[s..t]归并排序为TR[s..t]。

intm,TR1[100];

if(s==t)TR[s]=SR[s];

else{

m=(s+t)/2;

MSort(SR,TR1,n,s,m);//递归地将SR[s..m]归并为有序的TR1[s..m]。

MSort(SR,TR1,n,m+1,t);//递归地将SR[m+1..t]归并为有序的TR1[m+1..t]。

Merge(TR1,TR,n,s,m,t);//将TR1[s..m]、TR1[m+1..t]归并到TR1[s..t];

}

}

voidMergeSort(inta[],intn){

MSort(a,a,n,1,n);

}

intmain(){

inta[100],n,i;

printf("请输入要进行排序的数的个数n:

\n");

scanf("%d",&n);

printf("请输入这n个数:

\n");

for(i=1;i<=n;i++)//注意数组的起始位置。

scanf("%d",&a[i]);

MergeSort(a,n);

printf("排序后的n个数是:

\n");

for(i=1;i<=n;i++)

printf("%4d",a[i]);

printf("\n");

system("pause");

}

数据测试:

2、链表与数组

1、假定数组A[N]的n个元素中有多个零元素,编写算法将A中所有的非零元素依次移到A的前端。

【华中科技大学,06年】

代码:

#include

#include

intmain(){

inta[100],n,i;

while

(1){

printf("pleaseinputthenumberofthearray:

\n");

scanf("%d",&n);

printf("pleaseinputeveryvalueinthearray:

\n");

for(i=0;i

scanf("%d",&a[i]);

intp=-1,q=0,m=0;

for(i=0;i

if(a[i]==0){

if(!

q)p=i;//p记录第一个零元素的位置。

q++;//q记录已经遍历到的零元素的个数。

m++;

}

else{

if(p>0&&q>0){

a[p]=a[i];//移动非零元素至前面。

//a[i]=0;

q--;//零元素个数减1。

if(q>0)p++;

}

elseif(m>0)

a[i-m]=a[i];

}

printf("thevaluesafterremoving:

\n");

for(i=0;i

printf("%4d",a[i]);

printf("\n");

}

system("pause");

}

数据测试:

2、顺序存储的线性表,其数据元素为整型,试编写一算法,将A拆分成B和C两个表,使A中的元素值大于等于0的存入B,小于0的存入C中。

要求:

(1)表B和C另外设置存储空间。

(2)表B和C不另外设置,而利用A的空间。

(1)代码:

#include

#include

intmain(){

intA[10]={1,2,3,-4,-7,5,7,-9,8,-2};

intB[10],C[10];

inti,j,k;

i=j=k=0;

for(i=0;i<10;i++)

if(A[i]>=0)B[j++]=A[i];

elseC[k++]=A[i];

printf("拆分前:

\n");

printf("A:

");

for(i=0;i<10;i++)

printf("%4d",A[i]);

printf("\n");

printf("拆分后:

\n");

printf("B:

");

for(i=0;i

printf("%4d",B[i]);

printf("\n");

printf("C:

");

for(i=0;i

printf("%4d",C[i]);

printf("\n");

system("pause");

}

数据测试:

(2)代码:

#include

#include

intmain(){

intA[10]={1,2,3,-4,-7,5,7,-9,8,-2};

inti=0,j=9,temp,t=0;

printf("拆分前:

\n");

printf("A:

");

for(t=0;t<10;t++)

printf("%4d",A[t]);

printf("\n");

while(i<=j){

while(A[i]>=0)i++;

while(A[j]<0)j--;

if(i

temp=A[i];

A[i]=A[j];

A[j]=temp;

}

}

printf("拆分后:

\n");

printf("B:

");

for(t=0;t

printf("%4d",A[t]);

printf("\n");

printf("C:

");

for(t=i;t<9;t++)

printf("%4d",A[t]);

printf("\n");

system("pause");

}

数据测试:

3、逆置单链表

无头节点单链表,节点:

数据域data、指针域next,表头指针h。

通过遍历链表,将所有的指针方向逆转,其中表头指针指向最后一个节点。

算法:

voidInverse(&h){

if(h==null)return;

p=h->next;

pr=null;

while(p){

h->next=pr;

pr=h;

h=p;

p=p->next;

}

}

4、删除顺序表中元素

长度为n的线性表A采用顺序存储方式,写算法删除线性表中所有值为item的数据元素。

要求:

时间复杂度为O(n),空间复杂度为O

(1)。

5、将数组偶数移至奇数之前

设计将数组A[n]中所有的偶数移到奇数之前的算法。

要求:

不增加存储空间,且时间复杂度为O(n)。

代码:

#include

#include

intmain(){

intA[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

inti,j,x;

//x=A[0];

i=0;

j=19;

while(i

x=A[i];

while(A[j]%2==1)j--;

if(i

A[i]=A[j];

i++;

}

if(i

while(A[i]%2==0)i++;

if(i

A[j]=A[i];

j--;

}

A[i]=x;

}

for(i=0;i<20;i++)

printf("%d",A[i]);

printf("\n");

system("pause");

}

数据测试:

6、逆序输出单链表各元素

代码:

#include

#include

typedefstructnode{

chardata;

structnode*next;

}list;

typedeflist*link;

linkCreate(){//创建链表。

charch;

list*p;

linkhead;

head=NULL;

ch=getchar();

while(ch!

='\n'){

p=(list*)malloc(sizeof(list));

p->data=ch;

p->next=head;

head=p;

ch=getchar();

}

returnhead;

}

voidDisplay(linkhead){

list*p;

p=head;

printf("头插法建立的链表的输出结果:

\n");

while(p){

printf("%c",p->data);

p=p->next;

}

printf("\n");

}

intmain(){

linkhead;

printf("请输入链表的内容:

\n");

head=Create();

Display(head);

system("pause");

}

数据测试:

7、合并两个单链表(Ⅰ)

A为递增有序的单链表,长度为n。

B为递减有序的单链表,长度为m。

编写程序,利用原表的存储空间,将A、B合并成为一个递增有序的单链表。

要求:

时间复杂度为O(m+n)。

算法:

//先将单链表B逆转:

voidReverse(Node*r){

Node*q=r,*p=null,*temp;

while(q){

temp=q;

q=q->next;

temp->next=p;

p=temp;

}

r=p;

}

//再合并两个非递减的单链表:

Node*Merge(Node*a,Node*b){

Node*s,*r;

Node*p=a,*q=b;

while(p!

=NULL&&q!

=NULL){

if(p->datadata){

if(p==a){

s=a;

r=a;

}

elser->next=p;

p=p->next;

}

else{

if(q==b){

s=b;

r=b;

}

elser->next=q;

q=q->next;

}

r=r->next;

}

if(p==NULL&&q!

=NULL)r->next=q;

if(q==NULL&&p!

=NULL)r->next=p;

returns;

}

//主方法。

合并题目所给的两个单链表。

Node*MergeFunc(Node*a,Node*b){

Reverse(b);

Node*result=Merge(a,b);

resultresult;

}

8、合并两个单链表(Ⅱ)

单链表A、B,数据都为整型有序,编写程序,利用原节点,将A和B中具有相同数据的节点删除,并将B中与原A表不同数据的节点插入A中,保持A的递增有序。

算法:

voidMerge(Node*a,Node*b){

Node*p,*q,*previous;

Node*temp1,*temp2;

//假设a、b带头节点。

p=a->next;

q=b->next;

previous=a;

while(p!

=NULL&&q!

=NULL){

if(p->datadata){

previous=p;//previous指示p的前驱。

p=p->next;

}

elseif(p->data==q->data){

temp1=p;

p=p->next;

previous->next=p->next;

deletetemp;

}

else{

temp2=q;

q=q->next;

previous->next=temp;

temp->next=p;

previous=previous->next;

}

}

if(p==NULL&&q!

=NULL)previous->next=q;

}

9、两个单链表求∩和∪

已知2个按元素非递减的单链表A和B,设计一算法利用原表节点空间形成连续的新链表A’和B’,使得A’=A∪B,B’=A∩B。

算法:

voidAdjust(LinkList&A,LinkList&B){

//假设A、B带头结点。

pa=A;

pb=B;

while(pa->next!

=NULL&&pb->next!

=NULL){

if(pa->next->datanext->data)

pa=pa->next;

elseif(pa->next->data==pb->next->data){

pa=pa->next;

pb=pb->next;

}

else{

temp=pb->next;

pb->ne

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1