//2.17 2.18 单链表有无头结点的插入、删除比较
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<time.h>
#define LIST_INIT_SIZE 20
using namespace std;
typedef int Elemtype;//用int示例
typedef struct Node
{
Elemtype data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
//创建有头节点链表,尾插法
Node *createlisthead(int n)//n个节点
{
LinkList L;
LinkList p,q;//指向节点的指针p,q
int i;
srand(time(0));//初始化随机数种子
L=(LinkList )malloc(sizeof(Node));//头结点
q=L; //q要指向尾部
for(i=0;i<n;++i){
p=(LinkList)malloc(sizeof(Node));
p->data=rand()%1000+1;
q->next=p;
q=p;
}
q->next=NULL;
return L;
}
void print1(LinkList L)//有头结点
{
LinkList p;
printf("\nNow ,These records are:\n");
p=L->next;
if(p!=NULL)
do
{
printf("%d ",p->data);
p=p->next;
}while(p!=NULL);
cout<<endl;
}
bool listheadinsert(LinkList &L,int i,Elemtype e)//含头结点
{
int j;//计数器
LinkList p,q;
p=L;
j=1;
while(p&&j<i)
{
p=p->next;
++j;
}
if(!p||j>i) return false;
//现在p指向第i-1个结点
q=(LinkList)malloc(sizeof(Node));//生成新的结点
q->data=e;
q->next=p->next;//先接上
p->next=q;//后断开,接到新的结点上
return true;
}
bool listheaddelete(LinkList &L,int i,Elemtype &e)//含头结点
{
int j;
LinkList p,q;
p=L;
j=1;//j为计数器
while(p->next &&j<i)
{
p=p->next;
++j;
}
if(!(p->next)||j>i) return false;
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//创建无头节点链表,尾插法
Node *creat(int n)//无头结点
{
LinkList L;
LinkList p,q;//指向节点的指针p,q
int i;
srand(time(0));//初始化随机数种子
//L=(LinkList )malloc(sizeof(Node)); //头结点
//q=L; //q要指向尾部
L=(LinkList)malloc(sizeof(Node));
L->data=rand()%1000+1;
q=L;
for(i=0;i<n-1;++i){
p=(LinkList)malloc(sizeof(Node));
p->data=rand()%1000+1;
q->next=p;
q=p;
}
q->next=NULL;
return L;
}
void print2(LinkList head)//无头结点输出
{
LinkList p;
printf("\nNow ,These records are:\n");
p=head;
if(head!=NULL)
do
{
printf("%d ",p->data);
p=p->next;
}while(p!=NULL);
cout<<endl;
}
bool insert(LinkList &L,int i,Elemtype e)//无头结点
{
int j;//计数器
LinkList p,q;
p=L;
j=1;
if(i==1){
q=(LinkList)malloc(sizeof(Node));//生成新的结点
q->data=e;
q->next=p;
L=q;
return true;
}
else{
i=i-1;
while(p&&j<i)
{
p=p->next;
++j;
}
if(!p||j>i) return false;
//现在p指向第i-1个结点
q=(LinkList)malloc(sizeof(Node));//生成新的结点
q->data=e;
q->next=p->next;//先接上
p->next=q;//后断开,接到新的结点上
return true;
}
}
bool del(LinkList &L,int i,Elemtype &e)//无头结点
{
int j;
LinkList p,q;
p=L;
j=1;//j为计数器
if(i==1){
q=p;
p=q->next;
L=p;
e=q->data;
free(q);
return true;
}
else{
i=i-1;
while(p->next &&j<i)
{
p=p->next;
++j;
}
if(!(p->next)||j>i) return false;
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return true;
}
}
int main()
{
int i,e;
LinkList head1,head2;
cout<<"有头结点"<<endl;
head1=createlisthead(LIST_INIT_SIZE);//有头结点
cout<<"创建成功,下面打印"<<endl;
print1(head1);
cout<<"下面进行插入,请输入要插入的位置和元素"<<endl;
cin>>i>>e;
if(listheadinsert(head1,i,e)){
cout<<"成功插入在"<<i<<"位置上"<<endl;
cout<<"现在的链表为";
print1(head1);
}
else{
cout<<"删除失败"<<endl;
}
cout<<"下面进行删除,请输入要删除的序号(<20)"<<endl;
cin>>i;
if(listheaddelete(head1,i,e)){
cout<<"成功删除了"<<i<<"位置上的元素"<<e<<endl;
cout<<"现在的链表为";
print1(head1);
}
else{
cout<<"删除失败"<<endl;
}
cout<<endl<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
cout<<"无头结点"<<endl;
head2=creat(LIST_INIT_SIZE);//有头结点
cout<<"创建成功,下面打印"<<endl;
print2(head2);
cout<<"下面进行插入,请输入要插入的位置和元素"<<endl;
cin>>i>>e;
if(insert(head2,i,e)){
cout<<"成功插入在"<<i<<"位置上"<<endl;
cout<<"现在的链表为";
print2(head2);
}
else{
cout<<"删除失败"<<endl;
}
cout<<"下面进行删除,请输入要删除的序号(<20)"<<endl;
cin>>i;
if(del(head2,i,e)){
cout<<"成功删除了"<<i<<"位置上的元素"<<e<<endl;
cout<<"现在的链表为";
print2(head2);
}
else{
cout<<"删除失败"<<endl;
}
return 0;
}
//2.19 删除链表中指定区间的元素
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#define LIST_INIT_SIZE 20
using namespace std;
typedef int Elemtype;//用int示例
typedef struct Node
{
Elemtype data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
int arr[LIST_INIT_SIZE];
Node *createlist(int n)//创建链表
{
LinkList L;
LinkList p,q;//指向节点的指针p,q
int i;
//srand(time(0));//初始化随机数种子
L=(LinkList )malloc(sizeof(Node));//头结点
q=L; //q要指向尾部
for(i=0;i<n;++i){
p=(LinkList)malloc(sizeof(Node));
p->data=arr[i];
q->next=p;
q=p;
}
q->next=NULL;
return L;
}
void print(LinkList L)//有头结点
{
LinkList p;
printf("\nNow ,These records are:\n");
p=L->next;
if(p!=NULL)
do
{
printf("%d ",p->data);
p=p->next;
}while(p!=NULL);
cout<<endl;
}
bool listdelete_L(LinkList &L,Elemtype mink,Elemtype maxk)
{
LinkList p,q,prev=NULL;
if(mink>maxk) return false;
p=L;
prev=p;
p=p->next;
while(p&&p->data<maxk){
if(p->data<=mink){
prev=p;
p=p->next;
}
else{
prev->next=p->next;
q=p;
p=p->next;
free(q);
}
}
return true;
}
//算法的时间复杂度为O(n)
int main()
{
LinkList head;
Elemtype min,max;
srand(time(0));
for(int i=0;i<LIST_INIT_SIZE;++i){
arr[i]=rand()%1000+1;
}
sort(arr,arr+LIST_INIT_SIZE);//构建递增元素
head=createlist(LIST_INIT_SIZE);
cout<<"现在的链表为 ";
print(head);
cout<<"现在我们删除链表中在min:"<<min<<"和max"<<max<<"之间的元素"<<endl;
cout<<"请输入min和max(均为1000以内的整数)"<<endl;
cin>>min>>max;
if(listdelete_L(head,min,max)){
cout<<"操作成功"<<endl;
}
else{
cout<<"操作失败,请检查min和max"<<endl;
}
cout<<"现在的链表为 ";
print(head);
return 0;
}
//2.20 删除链表中相同的元素
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#define LIST_INIT_SIZE 20
using namespace std;
typedef int Elemtype;//用int示例
typedef struct Node
{
Elemtype data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
int arr[LIST_INIT_SIZE];
Node *createlist(int n)//创建链表
{
LinkList L;
LinkList p,q;//指向节点的指针p,q
int i;
//srand(time(0));//初始化随机数种子
L=(LinkList )malloc(sizeof(Node));//头结点
q=L; //q要指向尾部
for(i=0;i<n;++i){
p=(LinkList)malloc(sizeof(Node));
p->data=arr[i];
q->next=p;
q=p;
}
q->next=NULL;
return L;
}
void print(LinkList L)//有头结点
{
LinkList p;
printf("\nNow ,These records are:\n");
p=L->next;
if(p!=NULL)
do
{
printf("%d ",p->data);
p=p->next;
}while(p!=NULL);
cout<<endl;
}
void ListDelete_LSameNode(LinkList &L)
{
LinkList p,q,prev;
p=L;
prev=p;
p=p->next;
while(p)
{
prev=p;
p=p->next;
if(p&&p->data==prev->data){
prev->next=p->next;
q=p;
p=p->next;
free(q);
}
}
}
//该算法的时间复杂度为O(n)
int main()
{
char c;
LinkList head;
srand(time(0));
for(int i=0;i<LIST_INIT_SIZE;++i){
arr[i]=rand()%30+1;
}
sort(arr,arr+LIST_INIT_SIZE);//构建递增元素
head=createlist(LIST_INIT_SIZE);
cout<<"现在的链表为 ";
print(head);
cout<<"现在我们删除链表中所有重复的元素"<<endl;
cout<<"请点击字符s开始操作"<<endl;
cin>>c;
ListDelete_LSameNode(head);
cout<<"现在的链表为 ";
print(head);
return 0;
}
//2.21 顺序表的就地逆置
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#define LIST_INIT_SIZE 20
using namespace std;
typedef int Elemtype;//用int示例
typedef struct
{
Elemtype data[LIST_INIT_SIZE];
int length;
}SqList;
void listoppose_sq(SqList &L)
{
int i;
Elemtype x;
for(int i=0;i<L.length/2;++i){
x=L.data[i];
L.data[i]=L.data[L.length-1-i];
L.data[L.length-1-i]=x;
}
}
void creat(SqList &L)
{
srand(time(0));
for(int i=0;i<L.length;++i){
L.data[i]=rand()%1000+1;
}
}
void print(SqList L)
{
for(int i=0;i<L.length;++i){
cout<<L.data[i]<<' ';
}
cout<<endl;
}
int main()
{
char c;
SqList stu;
stu.length=LIST_INIT_SIZE;
creat(stu);
cout<<"初始的线性表为"<<endl;
print(stu);
cout<<endl<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
cout<<"下面我们对线性表就地逆置"<<endl;
cout<<"请点击字符s开始操作"<<endl;
cin>>c;
listoppose_sq(stu);
cout<<"现在的线性表为";
print(stu);
return 0;
}
//2.22 单链表就地逆置
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<time.h>
#define LIST_INIT_SIZE 20
using namespace std;
typedef int Elemtype;//用int示例
typedef struct Node
{
Elemtype data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
Node *createlist(int n)//n个节点
{
LinkList L;
LinkList p,q;//指向节点的指针p,q
int i;
srand(time(0));//初始化随机数种子
L=(LinkList )malloc(sizeof(Node));//头结点
q=L; //q要指向尾部
for(i=0;i<n;++i){
p=(LinkList)malloc(sizeof(Node));
p->data=rand()%1000+1;
q->next=p;
q=p;
}
q->next=NULL;
return L;
}
void print(LinkList L)//有头结点
{
LinkList p;
printf("\nNow ,These records are:\n");
p=L->next;
if(p!=NULL)
do
{
printf("%d ",p->data);
p=p->next;
}while(p!=NULL);
cout<<endl;
}
void ListOppose_L(LinkList &L)
{
LinkList p,q;
p=L;
p=p->next;
L->next=NULL;
while(p)
{
q=p;
p=p->next;
q->next=L->next;
L->next=q;
}
}
int main()
{
char c;
LinkList head;
srand(time(0));
head=createlist(LIST_INIT_SIZE);
cout<<"现在的链表为 ";
print(head);
cout<<endl<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
cout<<"下面我们对链表就地逆置"<<endl;
cout<<"请点击字符s开始操作"<<endl;
cin>>c;
ListOppose_L(head);
cout<<"现在的链表为 ";
print(head);
return 0;
}
//2.23 合并两个单链表
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<time.h>
//#define LIST_INIT_SIZE 20
using namespace std;
typedef int Elemtype;//用int示例
typedef struct Node
{
Elemtype data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
Node *createlist(int n)//n个节点
{
LinkList L;
LinkList p,q;//指向节点的指针p,q
int i;
srand(time(0));//初始化随机数种子
L=(LinkList )malloc(sizeof(Node));//头结点
q=L; //q要指向尾部
for(i=0;i<n;++i){
p=(LinkList)malloc(sizeof(Node));
p->data=rand()%1000+1;
q->next=p;
q=p;
}
q->next=NULL;
return L;
}
void print(LinkList L)//有头结点
{
LinkList p;
printf("\nNow ,These records are:\n");
p=L->next;
if(p!=NULL)
do
{
printf("%d ",p->data);
p=p->next;
}while(p!=NULL);
cout<<endl;
}
//将合并后的结果放到C表中,并删除B表
void ListMerge_L(LinkList &A,LinkList &B,LinkList &C)
{
LinkList pa,pb,qa,qb;
pa=A->next;
pb=B->next;
C=A;
while(pa&&pb)
{
qa=pa; qb=pb;
pa=pa->next; pb=pb->next;
qb->next=qa->next;
qa->next=qb;
}
if(!pa){
qb->next=pb;
}
pb=B;
free(pb);
}
int main()
{
char c;
int n,m;
LinkList head1,head2,head3;
srand(time(0));
cout<<"下面建立两个单链表,前输入他们的长度:"<<endl;
cin>>m>>n;
head1=createlist(m);
head2=createlist(n);
cout<<"现在的链表为 "<<endl;
print(head1);
print(head2);
cout<<endl<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
cout<<"下面我们对链表进行合并"<<endl;
cout<<"请点击字符s开始操作"<<endl;
cin>>c;
ListMerge_L(head1,head2,head3);
cout<<"合并后的链表为 ";
print(head3);
return 0;
}
//2.24 归并升序的A表和B表并转为非递增放在C表中
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#define LIST_INIT_SIZE 20
using namespace std;
typedef int Elemtype;//用int示例
int arr[LIST_INIT_SIZE];
typedef struct Node
{
Elemtype data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
Node *createlist(int n)//创建链表
{
LinkList L;
LinkList p,q;//指向节点的指针p,q
int i;
//srand(time(0));//初始化随机数种子
L=(LinkList )malloc(sizeof(Node));//头结点
q=L; //q要指向尾部
for(i=0;i<n;++i){
p=(LinkList)malloc(sizeof(Node));
p->data=arr[i];
q->next=p;
q=p;
}
q->next=NULL;
return L;
}
void print(LinkList L)//有头结点
{
LinkList p;
printf("\nNow ,These records are:\n");
p=L->next;
if(p!=NULL)
do
{
printf("%d ",p->data);
p=p->next;
}while(p!=NULL);
cout<<endl;
}
void ListMerge_L(LinkList &A,LinkList &B,LinkList &C)
{
LinkList pa,pb,qa,qb;
pa=A;
pb=B;
qa=pa; //保留pa的前驱指针
qb=pb; //保留pb的前驱指针
pa=pa->next;
pb=pb->next;
A->next=NULL;
C=A;
while(pa&&pb)
{
if(pa->data<pb->data){
qa=pa;
pa=pa->next;
qa->next=A->next;//将当前最小节点插入A表表头
A->next=qa;
}
else{
qb=pb;
pb=pb->next;
qb->next=A->next;//将当前最小节点插入A表表头
A->next=qb;
}
}
while(pa)
{
qa=pa;
pa=pa->next;
qa->next=A->next;
A->next=qa;
}
while(pb)
{
qb=pb;
pb=pb->next;
qb->next=A->next;
A->next=qb;
}
pb=B;
free(pb);
}
int main()
{
char c;
LinkList head1,head2,head3;
srand(time(0));
for(int i=0;i<LIST_INIT_SIZE;++i){
arr[i]=rand()%1000+1;
}
sort(arr,arr+LIST_INIT_SIZE);//构建递增元素
head1=createlist(LIST_INIT_SIZE);
for(int i=0;i<LIST_INIT_SIZE;++i){
arr[i]=rand()%1000+1;
}
sort(arr,arr+LIST_INIT_SIZE);
head2=createlist(LIST_INIT_SIZE);
cout<<"现在的两个链表为 "<<endl;
print(head1);
print(head2);
cout<<endl<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
cout<<"下面我们对链表进行合并"<<endl;
cout<<"请点击字符s开始操作"<<endl;
cin>>c;
ListMerge_L(head1,head2,head3);
cout<<"合并后的链表为 ";
print(head3);
return 0;
}