无序:与输入一致
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct List{
int value;
List *next;
int length;
};
List *head,*tail;//head头指针是个哨兵,无实际元素,tail尾指针也是哨兵,但有实际元素
void creat_list(int n){
List *p;
head=(List*)malloc(sizeof(List));
head->length=n;
head->next=NULL;
tail=head;
p=head;
for(int i=0;i<n;i++){
int temp;
scanf("%d",&temp);
List *tem;
tem=(List*)malloc(sizeof(List));
tem->value=temp;
tem->next=NULL;
p->next=tem;
p=p->next;
}
tail=p;
return;
}
void print(List *head){
if(head->length==0){
printf("List为空链表\n");
return;
}
List *p=head->next;
while(p!=NULL){
printf("%d ",p->value);
p=p->next;
}
printf("\n");
}
List* find(int x){
List *p=head->next;
while(p->value!=x && p!=NULL){
p=p->next;
}
return p;
}
void insert(int value){//无序链表,直接将元素插入到尾部
List *p;
p=(List*)malloc(sizeof(List));
p->value=value;
p->next=NULL;
tail->next=p;
tail=tail->next;
head->length++;
}
int insert1(int x,int value){//如果链表中有值x,在x前面插入value
List *p=head->next,*pre=head;
while(p->value!=x && p!=NULL){
pre=p;
p=p->next;
}
if(p==NULL) return -1;
else if(p->value==x){
List *node=(List*)malloc(sizeof(List));
node->value=value;
node->next=p;
pre->next=node;
return 1;
}
}
int delete_list(int value){//根据值删除节点
int sign=0;
List *p,*pre,*temp;
pre=head;
p=head->next;
while(p!=NULL){
if(p->value==value){
sign++;
pre->next=p->next;
temp=p;
p=p->next;
free(temp);
}
else{
pre=p;
p=p->next;
}
}
head->length-=sign;
return sign;
}
int delete_list1(int location){//根据位置(下标,0~n-1)删除节点
if(location>=head->length) return -1;
List *p,*pre,*temp;
pre=head;
p=head->next;
int i=0;
while(i<location){
pre=p;
p=p->next;
i++;
}
pre->next=p->next;
temp=p;
p=p->next;
free(temp);
head->length--;
return 1;
}
void reverse(){//链表倒置
List *p=head->next,*pre=head,*temp;
if(p==NULL){
printf("List为空链表\n");
return;
}
tail=p;
while(p!=NULL){
temp=p->next;
p->next=pre;
pre=p;
p=temp;
}
tail->next=NULL;
head->next=pre;
}
int main(){
int n;
scanf("%d",&n);
creat_list(n);
delete_list(1);
reverse();
print(head);
return 0;
}
有序链表,非递减
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct List{
int value;
List *next;
int length;
};
List *head,*tail;//head头指针是个哨兵,无实际元素,tail尾指针也是哨兵,但是有实际元素
void creat_list(int n){
List *p;
head=(List*)malloc(sizeof(List));
head->length=n;
tail=head;
for(int i=0;i<n;i++){
int temp;
scanf("%d",&temp);
List *tem;
tem=(List*)malloc(sizeof(List));
tem->value=temp;
tem->next=NULL;
if(head==tail){
head->next=tem;
tail=tail->next;
}
else{
if(temp>=tail->value){
tail->next=tem;
tail=tail->next;
}
else{
List *pre=head;
p=head->next;
while(p->value<temp){
pre=p;
p=p->next;
}
tem->next=p;
pre->next=tem;
}
}
}
return;
}
void print(List *head){
List *p=head->next;
if(head->length==0){
printf("空链表\n");
return;
}
while(p!=NULL){
printf("%d ",p->value);
p=p->next;
}
printf("\n");
}
void insert(int value){//有序链表,插入后依旧有序
List *p=head->next,*pre=head,*temp;
while(p->value<value || p==NULL){
pre=p;
p=p->next;
}
temp=(List*)malloc(sizeof(List));
temp->value=value;
pre->next=temp;
temp->next=p;
head->length++;
}
int delete_list(int value){//根据值删除节点
int sign=0;
List *p,*pre,*temp;
pre=head;
p=head->next;
while(p!=NULL){
if(p->value==value){
sign++;
pre->next=p->next;
temp=p;
p=p->next;
free(temp);
}
else{
pre=p;
p=p->next;
}
}
head->length-=sign;
return sign;
}
int delete_list1(int location){//根据位置(下标,0~n-1)删除节点
if(location>=head->length) return -1;
List *p,*pre,*temp;
pre=head;
p=head->next;
int i=0;
while(i<location){
pre=p;
p=p->next;
i++;
}
pre->next=p->next;
temp=p;
p=p->next;
free(temp);
head->length--;
return 1;
}
void reverse(){//链表倒置
List *p=head->next,*pre=head,*temp;
if(p==NULL){
printf("List为空链表\n");
return;
}
tail=p;
while(p!=NULL){
temp=p->next;
p->next=pre;
pre=p;
p=temp;
}
tail->next=NULL;
head->next=pre;
}
int main(){
int n;
scanf("%d",&n);
creat_list(n);
delete_list(1);
print(head);
return 0;
}
注:链表还有一种插入和建立链表的方法,每当放入一个新的元素,插到head头指针的后面,与输入逆序。
单链表常见面试题:https://blog.youkuaiyun.com/Dxx_xx4/article/details/80961905
循环链表(无序版):
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct List{
int value;
List *next;
int length;
};
List *head,*tail,*pre_tail;
/*
head头指针是个哨兵,无实际元素,tail尾指针也是哨兵,同样无实际元素
pre_tail指针为tail的直接前驱,方便进行直接插入尾部操作
*/
void creat_list(int n){
List *p;
head=(List*)malloc(sizeof(List));
tail=(List*)malloc(sizeof(List));
head->length=n;
head->next=tail;
tail->next=head;
p=head;
for(int i=0;i<n;i++){
int temp;
scanf("%d",&temp);
List *tem;
tem=(List*)malloc(sizeof(List));
tem->value=temp;
tem->next=tail;
p->next=tem;
p=p->next;
}
pre_tail=p;
return;
}
void print(List *head){
if(head->next==tail){
printf("List为空链表\n");
return;
}
List *p=head->next;
while(p!=tail){
printf("%d ",p->value);
p=p->next;
}
printf("\n");
}
List* find(int x){
List *p=head->next;
while(p->value!=x && p!=tail){
p=p->next;
}
return p;
}
void insert(int value){//无序链表,直接将元素插入到尾部,通过pre_tail快速插入
List *p;
p=(List*)malloc(sizeof(List));
p->value=value;
p->next=tail;
pre_tail->next=p;
pre_tail=pre_tail->next;
head->length++;
}
int insert1(int x,int value){//如果链表中有值x,在x前面插入value
List *p=head->next,*pre=head;
while(p->value!=x && p!=tail){
pre=p;
p=p->next;
}
if(p==tail) return -1;
else if(p->value==x){
List *node=(List*)malloc(sizeof(List));
node->value=value;
node->next=p;
pre->next=node;
return 1;
}
}
int delete_list(int value){//根据值删除节点
int sign=0;
List *p,*pre,*temp;
pre=head;
p=head->next;
while(p!=tail){
if(p->value==value){
sign++;
pre->next=p->next;
temp=p;
p=p->next;
free(temp);
}
else{
pre=p;
p=p->next;
}
}
head->length-=sign;
return sign;
}
int delete_list1(int location){//根据位置(下标,0~n-1)删除节点
if(location>=head->length) return -1;
List *p,*pre,*temp;
pre=head;
p=head->next;
int i=0;
while(i<location){
pre=p;
p=p->next;
i++;
}
pre->next=p->next;
temp=p;
p=p->next;
free(temp);
head->length--;
return 1;
}
void reverse(){//链表倒置
List *p=head->next,*pre=head,*temp;
if(p==tail){
printf("List为空链表\n");
return;
}
while(p!=tail){
temp=p->next;
p->next=pre;
pre=p;
p=temp;
}
tail->length=head->length;
p->next=pre;
head->next=tail;
temp=head;
head=tail;
tail=temp;
}
int main(){
int n;
scanf("%d",&n);
creat_list(n);
delete_list(1);
//reverse();
print(head);
return 0;
}
双向链表:
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct List{
int value;
List *next;
List *pre;
int length;
};
List *head,*tail;
/*
head头指针是个哨兵,无实际元素,tail尾指针也是哨兵,同样无实际元素
*/
void creat_list(int n){
List *p;
head=(List*)malloc(sizeof(List));
tail=(List*)malloc(sizeof(List));
head->length=n;
head->next=tail;
head->pre=tail; //此时的双向链表也是循环链表,head与tail相互连通
tail->next=head;
tail->pre=head;
p=head;
for(int i=0;i<n;i++){
int temp;
scanf("%d",&temp);
List *tem;
tem=(List*)malloc(sizeof(List));
tem->value=temp;
tem->next=tail;
tem->pre=p;
tail->pre=tem;
p->next=tem;
p=p->next;
}
return;
}
void print(List *head){
if(head->next==tail){
printf("List为空链表\n");
return;
}
List *p=head->next;
while(p!=tail){
printf("%d ",p->value);
p=p->next;
}
printf("\n");
}
List* find(int x){
List *p=head->next;
while(p->value!=x && p!=tail){
p=p->next;
}
return p;
}
void insert(int value){//无序链表,直接将元素插入到尾部
List *p;
p=(List*)malloc(sizeof(List));
p->value=value;
p->next=tail;
p->pre=tail->pre;
tail->pre->next=p;
tail->pre=p;
head->length++;
}
int insert1(int x,int value){//如果链表中有值x,在x前面插入value
List *p=head->next;
while(p->value!=x && p!=tail){
p=p->next;
}
if(p==tail) return -1;
else if(p->value==x){
List *node=(List*)malloc(sizeof(List));
node->value=value;
node->next=p;
node->pre=p->pre;
p->pre->next=node;
p->pre=node;
return 1;
}
}
int delete_list(int value){//根据值删除节点
int sign=0;
List *p,*temp;
p=head->next;
while(p!=tail){
if(p->value==value){
sign++;
temp=p;
p->pre->next=p->next;
p->next->pre=p->pre;
p=p->next;
free(temp);
}
else
p=p->next;
}
head->length-=sign;
return sign;
}
int delete_list1(int location){//根据位置(下标,0~n-1)删除节点
if(location>=head->length) return -1;
List *p,*temp;
p=head->next;
int i=0;
while(i<location){
p=p->next;
i++;
}
p->pre->next=p->next;
p->next->pre=p->pre;
free(p);
head->length--;
return 1;
}
void reverse(){//链表倒置
List *p=head,*temp,*next,*pre;
if(head->next==tail){
printf("List为空链表\n");
return;
}
while(p!=tail){
next=p->next;
pre=p->pre;
p->next=pre;
p->pre=next;
p=next;
}
tail->length=head->length;
tail->next=tail->pre;
tail->pre=head;
temp=head;
head=tail;
tail=temp;
}
int main(){
int n;
scanf("%d",&n);
creat_list(n);
delete_list(1);
reverse();
print(head);
return 0;
}
链表运用:
一、多项式相加的算法实现
#include<iostream>
#include<algorithm>
using namespace std;
typedef struct poly{
int coef,exp;
poly *next;
}Lpoly;
void scan(Lpoly *pa,Lpoly *pb){
Lpoly *p=pa;
int n;
cin>>n;
for(int i=0;i<n;i++){
Lpoly *t;
t=(Lpoly*)malloc(sizeof(Lpoly));//必须写在循环内部,每次给t分配新的空间,否则都是一样的地址,会出错
int coef,exp;
cin>>coef>>exp;
t->coef=coef;
t->exp=exp;
t->next=NULL;
p->next=t;
p=p->next;
}
p=pb;
for(int i=0;i<n;i++){
Lpoly *t;
t=(Lpoly*)malloc(sizeof(Lpoly));
int coef,exp;
cin>>coef>>exp;
t->coef=coef;
t->exp=exp;
t->next=NULL;
p->next=t;
p=p->next;
}
}
Lpoly *add_poly(Lpoly *pa,Lpoly *pb){
Lpoly *r,*p,*q;
p=pa->next;
q=pb->next;
r=pa;
while(p!=NULL && q!=NULL){
if(p->exp==q->exp){
int x=q->coef+p->coef;
if(x!=0){
p->coef=x;
r=p;
}
else{
r->next=p->next;
}
p=p->next;
q=q->next;
}
else if(p->exp>q->exp){
r->next=p;
r=p;
p=p->next;
}
else{
r->next=q;
r=q;
q=q->next;
}
}
if(p==NULL) r->next=q;
else r->next=p;
return pa;
}
print(Lpoly *head){
Lpoly *t=head->next;
while(t!=NULL){
cout<<"coef:"<<t->coef<<",exp:"<<t->exp<<" ";
t=t->next;
}
cout<<endl;
}
int main(){
Lpoly *pa,*pb,*pc;
pa=(Lpoly*)malloc(sizeof(Lpoly));
pb=(Lpoly*)malloc(sizeof(Lpoly));
pc=(Lpoly*)malloc(sizeof(Lpoly));
scan(pa,pb);//pa和pb先分配地址才能传,野指针不能进行传递
pc=add_poly(pa,pb);
print(pc);
return 0;
}
/*
4
6 13 2 10 -5 4 14 0
5 13 3 11 8 6 5 4
*/