感觉笔试的时候考单链表也挺多的,写一些基础的练练手,没有经过大量的测试,如果发现边界错误请留言
#include <iostream>
#include <cstdio>
#include <cstring>
#include <malloc.h>
using namespace std;
typedef int type;
typedef struct Node
{
type data;
struct Node *next;
}Node,*List;
//创建链表,输入0或者'\0'结尾
void create(List &head)
{
int temp;
Node *p;
p=head;
while(cin>>temp)
{
if(temp==0)
return;
Node *q=(List)malloc(sizeof(Node));
q->data=temp;
q->next=NULL;
p->next=q;
p=q;
}
// head=head->next;
}
//打印链表
void print(List head)
{
printf("当前链表为:\n");
while(head)
{
printf("%d ",head->data);
head=head->next;
}
printf("\n");
}
//获取链表的长度
int get_len(List head)
{
int num=0;
while(head)
{
num++;
head=head->next;
}
return num;
}
//删除值为t的节点
void del(List &head,type t)
{
List pre=head,cur=head;
if(cur->data==t)
{
head=head->next;
free(pre);
return ;
}
cur=cur->next;
while(cur)
{
if(cur->data==t)
{
if(cur->next==NULL)
{
free(cur);
return;
}
else
{
pre->next=cur->next;
free(cur);
return;
}
}
pre=pre->next;
cur=cur->next;
}
printf("cannot find %d!\n",t);
}
//在某位置上插入一个节点
void ins(List &head,int pos,type t)
{
Node *node=(List)malloc(sizeof(Node));
node->data=t;
node->next=NULL;
if(pos==0)
{
node->next=head;
head=node;
return ;
}
int num=1;
List pre=head,cur=head;
cur=cur->next;
while(cur)
{
if(pos==num)
{
node->next=cur;
pre->next=node;
return;
}
num++;
pre=pre->next;
cur=cur->next;
}
printf("position %d error!\n",pos);
}
//用冒泡实现的链表排序
void Sort(List &head)
{
if(head==NULL)
return;
for(List cur=head,nxt=head->next;nxt;cur=cur->next,nxt=nxt->next)
{
for(List cur=head,nxt=head->next;nxt;cur=cur->next,nxt=nxt->next)
{
if(cur->data>nxt->data)
{
type temp=cur->data;
cur->data=nxt->data;
nxt->data=temp;
}
}
}
}
//链表逆置
List Reverse(List head)
{
if(head==NULL||head->next==NULL)
{
return head;
}
List p1,p2,p3;
p1=head;
p2=head->next;
while(p2)
{
p3=p2->next;
p2->next=p1;
p1=p2;
p2=p3;
}
head->next=NULL;
return p1;
}
//合并两个链表,并且不占用多余内存,且实现去重复的效果
List merge(List a,List b)
{
if(a==NULL)
return b;
else if(b==NULL)
return a;
List chead=(List)malloc(sizeof(Node));
List c=chead;
while(a&&b) //思想就是将两个链表串起来
{
if(a->data<b->data)
{
c->next=a;
c=c->next;
a=a->next;
}
else if(a->data>b->data)
{
c->next=b;
c=c->next;
b=b->next;
}
else
{
c->next=a; //精髓,如果此时将c移动,当a是2,2,2,b是2,2,2的时候,不是只出了一个2
//而这么写证明下面的值肯定比当前的大,然后c自然会移动
b=b->next;
}
}
c->next=a?a:b;
return chead->next;
}
int main()
{
printf("输入链表,以0结尾\n");
List l=(List)malloc(sizeof(Node));
create(l);
l=l->next;
print(l);
printf("链表长度为:%d\n",get_len(l));
type t;
printf("输入要删除的值:");
scanf("%d",&t);
del(l,t);
print(l);
type pos;
printf("输入插入的位置和值:");
scanf("%d%d",&pos,&t);
ins(l,pos,t);
print(l);
Sort(l);
printf("------排序后的链表-------\n");
print(l);
printf("-输入要合并的新链表,以0结尾\n");
List ll=(List)malloc(sizeof(Node));
create(ll);
ll=ll->next;
Sort(ll);
printf("--------合并之后--------\n");
l=merge(l,ll);
print(l);
l=Reverse(l);
printf("------链表逆置后-------\n");
print(l);
free(l);
return 0;
}