#include <iostream>
using namespace std;
//单链表
typedef struct Lnode {
int data;
struct Lnode *next;
} Lnode, *Linklist;
bool initlist(Linklist &L) {
L = (Linklist)malloc(sizeof(Lnode));
if (!L) {
return 0;
}
L->next = NULL;
return 1;
}
bool lookforlist(Linklist L, int i, int &e) {
Linklist p = L;
int j = 0; //记录位置
while (j < i) { //或者用值查找条件为(p->data!=e)
p = p->next;
j++;
}
e = p->data;
return 1;
}
bool insertlist(Linklist &L, int i, int e) {
Linklist p = L, q;
int j = 0;
while (j < i - 1) {
p = p->next;
j++;
}
if (j != i - 1) {
return 0;
}
q = (Linklist)malloc(sizeof(Lnode));
q->data = e;
q->next = p->next;
p -> next = q;
return 1;
}
bool deletelist(Linklist &L, int i, int &e) {
Linklist p = L, q;
int j = 0;
while (j < i - 1) {
p = p->next;
j++;
}
if (j != i - 1) {
return 0;
}
q = p->next;
p->next = q->next;
e = q->data;
free(q);
return 1;
}
bool headcreatelist(Linklist &L) {
Linklist q;
int node;
initlist(L);
cout << "请逆序输入数字,以0结束" << endl;
cin >> node;
while (node) {
insertlist(L, 1, node);
cin >> node;
cin >> node;
}
return 1;
}
bool tailcreatelist(Linklist &L) {
Linklist p = L, q;
int node;
initlist(L);
cout << "请顺序输入数字,以0结束" << endl;
cin >> node;
while (node) {
q = (Linklist)malloc(sizeof(Lnode));
q->data = node;
q->next = NULL;
p -> next = q;
L = q;
}
return 1;
}
void displaylist(Linklist L) {
Linklist p = L->next;
while (p) {
cout << p->data << endl;
p = p->next;
}
}
int main () {
Linklist L;
int i;
int e ;
cout << "创建链表" << endl;
headcreatelist(L);
displaylist(L);
cout << "删除链表" << endl;
deletelist( L, 1, e);
displaylist(L);
cout << "插入链表" << endl;
insertlist( L, 2, 200);
displaylist(L);
lookforlist( L, 3, e);
// displaylist(L);
}
//链表应用题1
//一个单链表L与已知指向非头节点的指针p,现在要让一个已知结点S插入到p前面,要求0(1)复杂度
//要时间最短,不妨将s插入到p的后面,再将两个值一交换,这样可以,如果按正常的在前节点插入,复杂度0(n)
bool insert1(Linklist &L, Linklist p, Linklist s) {
s->next = p->next;
p->next = s;
int temp;
temp = s->data;
s->data = p->data;
p->data = temp;
return 1;
}
//Q2,单链表保存n个整数,且绝对值不大于m,要求删除多余节点,时间复杂度0(n)
//最容易想到就是将每一个数据与所有的遍历一遍,找到一样的就删除操作但是这样时间复杂度0(n^2),不行,所以用牺牲空间
//来成全时间,做一个数组,让他容量m+1,直接扫描一遍,默认值0,出现就变成1,下次如果非0就删除
bool oncenode(Linklist &L, int m) {
int *a = (int *)malloc((m + 1) * sizeof(int));
if(!*a){
printf("ERROR");
return 0;
}
for (int i = 0; i < m + 1; i++) {
a[i] = 0;
}
Linklist p = L, q;
while (p->next) {//注意让p往下走
int i = p->next->data;
if (a[i] == 0) {
a[i] = 1;
} else {
// q->data = a[i];
q = p->next;
p->next = q->next ;
free(q);
}
}
free(a);
return 1;
}
//Q3将两个递增的链表合并成一个非递增的有序链表,时间复杂度0(1),这里r指针作用关键,是让p,q指针回复到待比较中
bool together(Linklist &L,Linklist L1,Linklist L2){
Linklist p=L1->next,q=L2->next,r;//p,q指向首结点
L=L1;//以L1的头节点作为合并后L的头结点,不用再次创建一个了,这里错过
L->next=NULL;//
if(p&&q){
if(p->data<=q->data){
r=p->next;
p->next =L->next ;
L->next=p;
p=r; ///这里将p恢复到L1中带比较的指针,这里错过
}
else{
r=q->next;
q->next =L->next ;
L->next=q;
q=r;
}
}
while(p){
r=p->next;
p->next =L->next ;
L->next=p;
p=r;
}
while(q){
r=q->next;
q->next =L->next ;
L->next=q;
q=r;
}
free(L2);//这里错过,如果L是新建的。不是直接用L1的,还要释放L1
return 1;
}
//Q4一元多项式加法,当指数差别过大,用数组的方法过于浪费空间,用链表的方法
typedef struct Polynode{
float coef;//表示系数
int expn;//表示指数
struct Polynode* next;
}Polynode,*Polylinklist;
bool signalsum(Polylinklist &La,Polylinklist Lb){
Polylinklist p=La->next;
Polylinklist q=Lb->next;
Polylinklist r=La,temp;
while(p&&q){
if(p->expn<q->expn){
r->next=p;//接入尾节点
r=p;//r始终是尾节点
p=p->next;//让p往下移动
}
if(p->expn>q->expn){
r->next=q;
r=q;
q=q->next;
}
else{
float sum=p->coef+q->coef;
if(sum!0){
p->coef=sum;
r->next=p;//接入尾节点
r=p;//r始终是尾节点
p=p->next;//让p往下
//再删除q
temp=q;
q=q->next;
free(temp);
}
else{//如果和为0,p,q往下移动,并且删除p,
temp=p->next;
free(p);
p=temp;
temp=q->next;
free(q);
q=temp;
}
}
}
r->next=(p=NULL)?q:p;
free(Lb);
retnrn 1;
}
//学习双向循环链表
typedef struct Dunode{
int data;
struct Dunode* next;
struct Dunode* prior;
}Dunode,*DuLinklist;//注意这里*加前面
bool initDunode(DuLinklist&L){
L=(DuLinklist)malloc(sizeof(Dunode));//这里错过,要先分配储存空间
L->next=L->prior=L;//next 与prior都指向头节点
}
//插入操作
bool insertDunode(DuLinklist&L,int j,int e){
DuLinklist p=L,q;
for(int i=0;i<j;i++){//这里错过,注意区别于单链表,这里找到j,而不是前一个
p=p->next ;
}
q=(DuLinklist)malloc(sizeof(Dunode));
if(!q){
printf("分配空间失败");
return 0;
}
q->data=e;
q->next =p;
q->prior=p->prior ;
q->prior->next=q;
p->prior =q;
return 1;
}
//删除操作
bool deleteDunode(DuLinklist&L,int j,int &e){
DuLinklist p=L,q;
for(int i=0;i<j;i++){
p=p->next ;
}
p->next->prior=p->prior;
p->prior->next=p->next;
p->data=e;
free(p);
}
//应用,约瑟夫问题