#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
#define Maxsize 50
#define InisSize 100
typedef struct SNode { //定义单链表结点类型
ElemType data;
struct SNode * next;
}SNode, *SLinklist;
typedef struct List { //管理循环单链表
SNode* first; //指向第一个节点(头节点)
SNode* last; //指向最后一个节点
int size;
}List;//管理链表头尾节点
typedef struct DNode { //定义双链表结点类型
ElemType data;
struct DNode* prior, * next;
}DNode,*DLinklist;
typedef struct DList { // 管理循环双链表
DNode* first;
DNode* last;
int size;
}DList;
typedef struct LNode {//链式结构
char ch;
ElemType data;
struct LNode* next;/*/p/*/
}LNode,*LinkList;
typedef struct {
int* data;
int MaxSize, length;
}SeqList;
//表的基操
bool ListInsert(SeqList* L, int i, int e); //顺序表插入
bool ListDelete(SeqList* L, int i, ElemType* e);//顺序表删除
int LocateElem(SeqList L, ElemType e); //顺序表查找
LinkList List_HeadInsert(LinkList L); //采用头插法 建立单链表
bool ListInsert_i(LinkList L,int i,ElemType e);//插入链表第i个位置
LinkList List_TailInsert(LinkList L); //采用尾插法 建立单链表
LNode* GetElem(LinkList L, int i); // 查找第i个节点并将该节点返回
bool List_delete(LinkList L, int i); //删除链表第i位置的节点
int List_Length(LinkList L); //获得链表的长度
LinkList List_Reverse(LinkList L); //单链表的逆置 (头插法/迭代) O(1)
LinkList List_Reverse2(LinkList L); //单链表的逆置 (递归)
void ReverseDoubleList(DList L); //逆置一个含有两个以上节点的循环双链表。
//单循环链表
void SLinkList_create(List *list); //循环单链表的初始化
void push_back(List* list, ElemType e); //循环单链表尾插法
void show_list(List* list); //打印循环单链表数据
SNode* getNode(ElemType e); //创建新结点
void push_front(List* list, ElemType n); //循环单链表头插法
void pop_back(List* list); //循环链表尾删法
void pop_front(List* list); //循环链表头删法
//双循环链表
void DLinkList_create(DList* list); //双循环链表初始化
DNode* getDNode(ElemType e); //创建新节点
void push_backD(DList* list, ElemType e); //双循环链表尾插
void push_frontD(DList* list, ElemType e); //双循环链表头插
void pop_backD(DList* list); //双循环链表尾删
void pop_frontD(DList* list); //双循环链表头删
void show_listD(DList* list); //打印双链表数据
//p17 ,01
void delx(SeqList* s,int x);
//02
void reverse(SeqList* s);
//03
int delMin(SeqList* s);
//04有序,05无序
void del_s_t(SeqList* l,int s,int t); //删除介于s和t的所有元素
//06 有无序均适合
void del_repeat(SeqList* s);
//07
SeqList mergeList(SeqList* s1,SeqList* s2);
//08
void exchage(int array[],int n,int m,int arraySize);
void reverse(int array[],int left,int right,int arraySize);
//09
void Binary_Search_List(SeqList* s,int key);
//10
void reverse(int R[],int from,int to);
void Converse(int R[],int n,int p);
//038, 01
void del_x(LinkList l,ElemType e);
//02
void del_x1(LinkList l,ElemType e);
//03
void print(LinkList l);
//04
void del_min(LinkList l);
//05
void reverse(LinkList l);
//06
void Sort(LinkList l);
//07 删除介于min与max之间的数
void del_min_max(LinkList l,int min,int max);
//08
LinkList find_com_node(LinkList l1,LinkList l2);
int length(LinkList l);
//09
void del_list(LinkList l);
//10
LinkList discrete_one_two(LinkList l);
//11
LinkList discrete_one_two_2(LinkList l);
//12
void remove_repeat(LinkList l);
//13
LinkList mergeLinkList(LinkList l1,LinkList l2);
//14
LinkList mergeA_B(LinkList l1,LinkList l2);
//15
void search_jiaoji(LinkList A,LinkList B);
//16
int Is_childList(LinkList l1,LinkList l2);
//int KMP_Is_childList(LinkList l1,LinkList l2);
//17
int isSymmetry(DList* list);
//18
void merge_oneCycleList(List* list1,List* list2);
//19
void del_min_onecycleList(List* list);
//21
SNode* isCycleList(List* list);
//24
void func(LinkList l,int n);
//25
void chang_list(LinkList l);
int Is_qian_N_duichen(LinkList head,int n); //判断不带头结点的单链表前n个字符是否中心对称
LNode* Fast_Find_Mid_Node(LinkList l); //快速找到未知长度链表的中间节点
LinkList ji_ou_List(LinkList l); //将奇数结点偶数结点排在一起,且偶数结点再奇数节点后
LinkList remove_end_n(LinkList l,int n); //删除链表倒数第n个结点
LinkList MergeTowList(LinkList l1,LinkList l2); //递归合并两个有序链表
LNode* getIntersectionNode(LinkList l1,LinkList l2); //递归找到相交链表
int Is_Symmestery(LinkList l,int n);
int Mergelistl1_l2(LinkList l1,LinkList l2,LinkList l3);
int main() {
// LinkList l,l2,l1;
//
// l1 = List_TailInsert(l1);
// l2 = List_TailInsert(l2);
// KMP_Is_childList(l1,l2);
// int flag = Is_childList(l1,l2);
// printf("%d",flag);
// if(flag == 1){
// printf("成功");
// }else if(flag == 0){
// printf("失败");
// }
// search_jiaoji(l1,l2);
// l = mergeA_B(l1,l2);
// l = mergeLinkList(l1,l2);
// remove_repeat(l);
// l2 = discrete_one_two_2(l);
// A = discrete_one_two(l);
// Sort(l);
// del_min_max(l,3,5);
// del_list(l);
// l = l->next;
// del_x1(l,3);
// print(l);
// del_min(l);
// reverse(l);
// l = l->next;
// l1 = l1->next;
// while(l!=NULL){ //l起始结点为有效结点
// printf("%d ",l->data);
// l = l->next;
// }
// putchar('\n');
// l2 = l2->next;
// while(l2!=NULL){ //l起始结点为有效结点
// printf("%d ",l2->data);
// l2 = l2->next;
// }
// SeqList
// DList list;
// DLinkList_create(&list);
for(int i = 0; i < 5; i++){
// push_frontD(&list,0);
// push_frontD(&list,3);
// push_frontD(&list,3);
// push_frontD(&list,2);
// push_frontD(&list,0);
}
// if(isSymmetry(&list)){
// printf("对称");
// }else{
// printf("不对称");
// }
// putchar('\n');
// show_listD(&list);
// putchar('\n');
// pop_frontD(&list);
// show_listD(&list);
//
//
// List list1,list2;
// SLinkList_create(&list1);
// SLinkList_create(&list2);
// for(int i = 0; i < 5; i++){
// push_back(&list1,1);
// push_back(&list1,5);
// push_back(&list1,4);
// push_back(&list1,3);
// push_back(&list1,8);
// push_back(&list2,i);
// }
// merge_oneCycleList(&list1,&list2);
// del_min_onecycleList(&list1);
// show_list(&list1);
// show_list(&list2);
//
//
// printf("\n");
// pop_front(&list);
// pop_front(&list);
// show_list(&list);
//
// DLinklist DL = DLinkList_create();
// if(DL){
// printf("创建成功");
// }else{
// printf("创建失败");
// }
LinkList L,L1,L2 = NULL;
L = List_TailInsert(L);
// L = L->next;
L1 = List_TailInsert(L1);
// L1 = L1->next;
// L = List_Reverse2(L);
// L = ji_ou_List(L);
// L = MergeTowList(L,L1);
int num = Mergelistl1_l2(L,L1,L2);
printf("%d",L2->next->data);
L2 = L2->next;
// int length = List_Length(L);
// printf("%d\n",length);
// List_delete(L,3);
// if(ListInsert_i(L,3,100)){
// printf("插入成功\n");
// }else{
// printf("插入失败\n");
// }
// LNode* l = GetElem(L,4);
// if(l){
// printf("%d\n",l->data);
// }
// L = L->next;
while(1){
if(L2!=NULL){
printf("%d ",L2->data);
L = L2->next;
}
if(L2 == NULL)break;
}
// SeqList s;
// int e;
// s.data = (int*)malloc(sizeof(int) * 50);
// bool b =ListInsert(&s, 1, 1);
// ListInsert(&s, 2, 2);
// ListInsert(&s, 3, 3);
// ListInsert(&s, 4, 4);
// ListInsert(&s, 5, 5);
// ListInsert(&s, 6, 5);
// ListInsert(&s, 7, 7);
// Binary_Search_List(&s,7);
// for(int i = 0; i < s.length; i++)printf("%d ",s.data[i]);
// SeqList s2 = mergeList(&s,&s1);
// int data = LocateElem(s,4);
// if(data != 0){
// printf("查找成功%d\n",data);
// }else{
// printf("查找失败%d\n",data);
// }
ListDelete(&s,1,&e);
printf("删除了%d\n",e);
// delx(&s,3);
// del_repeat(&s);
//
// for(int i = 0; i < s2.length; i++)
// printf("%d ",s2.data[i]);
return 0;
}//链表的顺序存储 插入
bool ListInsert(SeqList* L, int i, int e) {
if (i<1 || i>L->length+1) { //超过范围
return false;
}
if (L->length == Maxsize) { //链表已满
return false;
}
for (int j = L->length; j >= i; j--) {
L->data[j] = L->data[j - 1];
}
L->data[i - 1] = e; //插入第i个位置
L->length++; //length初始为0;
return true;
}
//顺序表删除
bool ListDelete(SeqList* L, int i, ElemType* e) {
if (i < 1 || i>L->length) {
return false;
}
if (L->length == 0)return false;
*e = L->data[i - 1];
for (int j = i-1; j < L->length; j++) {
L->data[j] = L->data[j];
}
L->length--;
return true;
}
int LocateElem(SeqList L, ElemType e) {
for (int i = 0; i < L.length; i++) {
if (L.data[i] == e)return i + 1;
}
return 0;
}
//采用头插法 建立单链表
LinkList List_HeadInsert(LinkList L) {
LNode* s; int x;
L = (LinkList)malloc(sizeof(LNode)); //创建头节点
L->next = NULL;
scanf("%d", &x);
while (x != 0) { //0表示输入结束
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
L->next = s;
scanf("%d", &x);
}
return L;
}
//插入链表第i个位置
bool ListInsert_i(LinkList L, int i, ElemType e) {
LNode* s;
LinkList l;
int j = 1;
l = L;
while (l && j < i) {//查找第i个位置
j++;
l = l->next;
}
if (!l || j > i)return false;//不存在第i个位置
s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = l->next;
l->next = s;
return true;
}
//采用尾插法建立单链表
LinkList List_TailInsert(LinkList L) {
int x;
L = (LinkList)malloc(sizeof(LNode));
LNode* s, * r = L;
scanf("%d", &x);
while (x != 0) {
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;
scanf("%d", &x);
}
r->next = NULL;
return L;
}
// 查找第i个节点并将该节点返回
LNode* GetElem(LinkList L, int i) {
if (i < 1)return NULL;
int j = 1;
LNode* p = L->next; //找到第一个节点
while (p && j < i){
p = p->next;
j++;
}
return p;
}
//删除链表第i位置的节点
bool List_delete(LinkList L, int i) {
int j = 0;
LNode* n = L, * N;
while (n && j < i - 1) { //找到第i-1位置的节点
n = n->next;
j++;
}
if (n == NULL || j != i - 1 || n->next == NULL) {
return false;
}else{
N = n->next;
n->next = N->next;
free(N);
return true;
}
}
//获得链表的长度
int List_Length(LinkList L) {
int length = 0;
LNode* N = L->next;//先指第一个有效的节点
while (N) {
length++;
N = N->next;
}
return length;
}
//单链表的逆置 (头插法) O(1)
LinkList List_Reverse(LinkList L) {
LNode* L1 = L->next,*L2; //L1记录原来链表有效节点位置,L2作为遍历节点
L->next = NULL; //致L2后继位空作为头节点
while (L1) {
L2 = L1->next; //标记L1指向后一个节点记为L2
L1->next = L->next; //将L1后继改为L1头节点的下一个位置
L->next = L1; //将L1作为表头 的下一个位置作为头
L1 = L2; //L1改为原来位置的后继
}
return L; //返回新链表的头指针
}
//单链表的逆置 (递归) 注意开始调用从头节点后一个有效结点开始
LinkList List_Reverse2(LinkList L) {
if (L == NULL || L->next == NULL) {
return L;
}
LinkList newhead = List_Reverse2(L->next); //递归找到最后一个节点
L->next->next = L; //反转链表
L->next = NULL;
return newhead;
}
void ReverseDoubleList(DList L){ //逆置双循环链表
DNode* begin = L.first;
DNode* end = L.last;
while(begin != end && begin->prior != end){
ElemType temp = begin->data; //逆置双循环链表实际就将内部数据交换
begin->data = end->data;
end->data = temp;
begin = begin->next;
end = end->prior;
}
}
DLinklist DLinkList_create() {
DNode* DL = (DLinklist)malloc(sizeof(DNode));
if (DL == NULL) {
printf("创建失败");
return NULL;
}
DL->prior = DL;
DL->next = DL;
return DL;
}
//循环单链表的初始化
void SLinkList_create(List *list) {
SNode* L = (SNode*)malloc(sizeof(SNode));
if (L != NULL){//初始化一个空的头节点
list->first = list->last = L;
list->last->next = list->first;
list->size = 0;
}
}
//循环单链表尾插法
void push_back(List* list,ElemType e) {
SNode* p = getNode(e);
list->last->next = p; //插入新结点
list->last = p; //更改管理结点指向尾接点
list->last->next = list->first; //重新形成循环
list->size++; //有效结点数加一
}
//打印循环单链表数据
void show_list(List* list) {
if(list->size == 0)return ;
SNode* p = list->first->next; //指向第一个有效数据
while (p != list->first) { //不等于头节点一直输出
printf("%d ", p->data);
p = p->next;
}
}
//创建新结点
SNode* getNode(ElemType e) {
SNode* p = (SNode*)malloc(sizeof(SNode));
if (p != NULL) {
p->data = e;
p->next = NULL;
return p;
}
return NULL;
}
//循环单链表尾插法
void push_front(List* list, ElemType e) {
SNode* p = getNode(e);
p->next = list->first->next;
list->first->next = p;
if (list->first == list->last) { //表示当添加第一个有效结点时更新管理结点尾结点
list->last = p;
}
list->size++;
}
//循环链表尾删法
void pop_back(List* list) {
if (list->size == 0) {
return ;
}
SNode* p = list->first;
while (p->next != list->last) { //找到最后一个结点的前一个节点
p = p->next;
}
free(list->last); //删除最后一个结点
list->last = p; //重新指向最后一个结点
list->last->next = list->first; //重新形成循环
list->size--; //个数减一
}
//循环链表头删法
void pop_front(List* list) {
if (list->size == 0) {
return;
}
SNode* p = list->first->next; //p指向第一个有效结点也就是要被删除的结点
list->first->next = p->next;
free(p);
if (list->size == 1) { //若被删除的结点前只有一个更改管理表头尾指针
list->first = list->last;
}
list->size--;
}
//双循环链表初始化
void DLinkList_create(DList* list) {
DNode* p = (DNode*)malloc(sizeof(DNode));
if (p == NULL) {
printf("创建失败");
return;
}
list->first = list->last = p;
list->first->prior = list->last; //形成双循环
list->last->next = list->first;
list->size = 0;
}
//创建新结点
DNode* getDNode(ElemType e){
DNode* p = (DNode*)malloc(sizeof(DNode));
if (p) {
p->data = e;
p->next = p->prior = NULL;
return p;
}
return NULL;
}
//双循环链表尾插法
void push_backD(DList* list, ElemType e){
DNode* p = getDNode(e);
p->next = list->last->next; //插入结点与尾结点后继连接 形成尾结点
p->next->prior = p;
p->prior = list->last; //插入结点与上一个尾接点连接
list->last->next = p;
list->last = p; //更新尾结点
list->size++;
}
//打印双循环链表
void show_listD(DList* list) {
if(list->size == 0)return ;
DNode* p = list->first->next; //指向第一个有效数据
while (p != list->first){
printf("%d ", p->data);
p = p->next;
}
}
//双循环链表头插
void push_frontD(DList* list, ElemType e) {
DNode* p = getDNode(e);
p->next = list->first->next;
p->next->prior = p;
p->prior = list->first;
list->first->next = p;
if (list->first == list->last) { //若插入时没有有效结点更改尾结点
list->last = p;
}
list->size++;
}
//双循环链表尾删
void pop_backD(DList* list) {
if (list->size == 0) {
return;
}
DNode* p = list->last;
list->last = p->prior; //更改尾结点
p->next->prior = list->last;
list->last->next = p->next;
free(p);
list->size--;
}
//双循环链表头删
void pop_frontD(DList* list) {
if (list->size == 0) {
return;
}
DNode* p = list->first->next; //指向第一个有效结点
p->next->prior = list->first; //更改删除节点的指向
list->first->next = p->next;
free(p);
if (list->size == 1) { //若删除时只有一个结点更改链表管理结点指向
list->first = list->last;
}
list->size--;
}
int delMin(SeqList* s){//删除最小元素
if(s->length == 0)return -1;//表空不操作
int i = 0,min = 0;
for(i = 1; i < s->length; i++){
if(s->data[i]<s->data[min])min = i;
}
int Min = s->data[min];
s->data[min] = s->data[s->length-1];
s->length--;
return Min;
}
//删除顺序表为x的数
void delx(SeqList* s,int x){
int k = 0, i = 0,sum = 0;
while(i < s->length){
if(s->data[i] == x)k++;
else s->data[i-k] = s->data[i];
i++;
}
s->length = s->length-k;
// printf("%d\n",s->length);
}
void reverse(SeqList* s){//逆置顺序表
int temp;
for(int i = 0; i < s->length/2; i++){
temp = s->data[i];
s->data[i] = s->data[s->length-i-1];
s->data[s->length-i-1] = temp;
}
}
void del_s_t(SeqList* l,int s,int t){//删除给定值s-t之间所有元素
if(s >= t || l->length == 0)return;
int k = 0;
for(int i = 0; i < l->length; i++){
if(l->data[i]>=s&&l->data[i]<=t){
k++;
} else{
l->data[i-k] = l->data[i];
}
}
l->length = l->length-k;
}
void del_repeat(SeqList* s){// 删除有序顺序表所有重复元素
int len = 1,j = 1,i = 0;
while(j < s->length){
for(i = 0; i < len; i++){
if(s->data[i] == s->data[j])break;
}
if(i == len){ //正常退出
s->data[len++] = s->data[j++]; //将j所指数据赋值到不重复的顺序表中(对原来值进行覆盖)
}else{
j++; //有重复值,则该j就不赋了进行下次比较
}
}
s->length = len;//重新修改顺序表长度
}
SeqList mergeList(SeqList* s1,SeqList* s2){//俩有序顺序表合并一个有序顺序表
SeqList s;
s.data = (int*)malloc(sizeof(int) * (s1->length+s2->length));
int i = 0, j = 0;
while(i < s1->length && j < s2->length){
if(s1->data[i] <= s2->data[j]){
s.data[s.length++] = s1->data[i];
i++;
}else{
s.data[s.length++] = s2->data[j];
j++;
}
}
while(i<s1->length){
s.data[s.length++] = s1->data[i];
i++;
}
while(j<s2->length){
s.data[s.length++] = s2->data[j];
j++;
}
return s;
}
void exchage(int array[],int m,int n,int arraySize){//数组中存入a1---am,b1---bn变为b1---bn,a1---am
reverse(array,0,n+m-1,arraySize);
reverse(array,0,n-1,arraySize);
reverse(array,n,n+m-1,arraySize);
}
void reverse(int array[],int left,int right,int arraySize){
if(left >= right || right >= arraySize)return;
int j = 0;
for(int i = left; i <= (left+right)/2; i++){
int temp = array[i];
array[i] = array[right-j];
array[right-j] = temp;
j++;
}
}
void Binary_Search_List(SeqList* s,int key){//找k,若存在与后继交换否则插入使表递增
int low = 0,height = s->length-1;
int mid;
while(low <= height){
mid = (low+height)/2;
if(s->data[mid] == key){
break;
}else if(s->data[mid] < key){
low = mid+1;
}else{
height = mid-1;
}
}
if(s->data[mid] == key && s->data[mid]!=s->data[s->length-1]){//若存在 且不是最后一个元素(没有后继)
int temp = s->data[mid];
s->data[mid] = s->data[mid+1];
s->data[mid+1] = temp;
}
if(low > height){ //最后排序结束时low = height+1,将未找到的值插入low所指的位置
int i;
for(i = s->length; i > low;i--){
s->data[i] = s->data[i-1];
}
s->data[i] = key;//插入该值
s->length++;
}
}
void del_x(LinkList l,ElemType e){//删除不带头结点所有值为x结点
if(l == NULL)return;
if(l->data == e){ //防止断链,将删除的结点改为删除其后面一个结点
LNode* p = l->next;
l->data = p->data;
l->next = p->next;
free(p);
del_x(l,e); //再从l递归防止l也为要删除的结点
}else{
del_x(l->next,e);
}
}
void del_x1(LinkList l,ElemType e){//带头结点栓除所有x结点
LNode* p;
l = l->next;
while(l){
if(l->data == e){
p = l->next;
l->data = p->data;
l->next = p->next;
free(p);
}else l = l->next;
}
}
void print(LinkList l){//从尾到头反向输出每个节点
l = l->next;
if(l == NULL){
return;
}
if(l != NULL){
print(l);
printf("%d ",l->data);
}
}
void del_min(LinkList l){//带头结点链表删除最小节点
LNode* min = l->next,*p;
l = min->next;
while(l!=NULL){
if(min->data>l->data)min = l;
l = l->next;
}
p = min->next;
min->data = p->data;
min->next = p->next;
free(p);
}
void reverse(LinkList l){//单链表就地逆置空间复杂度O(1)
LNode *p1 = l->next,*p3;
l->next = NULL; //最后l依然是头结点
while(p1){
p3 = p1->next; //保存后继
p1->next = l->next; //p1结点连在头结点后
l->next= p1; //重新定位头
p1 = p3;
}
}
//构造单结点链表以此从原来链表找一个合适结点插入进来
void Sort(LinkList l){
LNode* p = l->next,*pre;
LNode* r = p->next;
p->next = NULL; //构造只含有一个数据节点的有序表
p = r; //指向第二个有效结点
while(p!=NULL){
r = p->next; //保存后继结点
pre = l;
while(pre->next != NULL && pre->next->data < p->data)pre = pre->next;
p->next = pre->next;
pre->next = p;
p = r;
}
}
void del_min_max(LinkList l,int min,int max){//删除介于Min和max之间的元素
LNode* p = l->next;
while(p != NULL){
if(p->data >= min && p->data <= max){
LNode* temp = p->next;
p->data = temp->data;
p->next = temp->next;
free(temp);
}else{
p = p->next;
}
}
}
/*分析
一但发现公共结点则从该结点到尾一定全是公共结点(因为结点只有一个后继)
则公共结点的长度相同, 则考虑若不同长度的链表
通过先遍历长的达到最后长度和短的一样再共同遍历、
找到共同结点
*/
LinkList find_com_node(LinkList l1,LinkList l2){
int len1,len2,cha; //1表长度,2表长度,两表之差
LinkList longList,shortList; //长链表 短链表
len1 = length(l1);
len2 = length(l2);
if(len1 > len2){
longList = l1->next;
shortList = l2->next;
cha = (len1-len2);
}else{
longList = l2->next;
shortList = l1->next;
cha = (len2-len1);
}
while(cha--){
longList = longList->next; //循环找到从该链表与短链表到尾长度相同的结点
}
while(longList){
if(longList != shortList){
longList = longList->next;
shortList = shortList->next;
}else return longList; //找到第一个相同的结点从这以后全相同
}
return NULL;
}
LNode* getIntersectionNode(LinkList l1,LinkList l2){//递归找到相交链表
LNode* head1 = l1,*head2 = l2;
while(l1 != l2){//最后两指针分别遍历对面,长的指针重新遍历到短的指针时,短的指针所指当前链表与长指针一样长
l1 = l1?l1->next:head2;
l2 = l2?l2->next:head1;
}
return l1;//l2;
}
int length(LinkList l){
int length = 0;
l = l->next;
while(l){
length++;
l = l->next;
}
return length;
}
void del_list(LinkList l){//但头结点链表,递增输出单链表各节点
LNode* head = l,*pre = l,*min = l->next;
while(head->next){
while(head->next){//遍历找出最小结点
if(head->next->data < min->data){
min = head->next;
pre = head;
}
head = head->next;
}//输出并释放空间,再次重新从头开始找第二小结点
printf("%d ",min->data);
pre->next = min->next;
free(min);
min = l->next;
head = l;
pre = l;
}
free(head);
}
//将l奇结点断链存到l1中 ,剩下偶节点还在L中
LinkList discrete_one_two(LinkList l){
LinkList l1 = (LinkList)malloc(sizeof(LNode));//l1存储奇结点
LNode *p = l->next,*q,*r,*pre;
int count = 1;
r = l1;//l1尾结点
r->next = NULL;
pre = l;
while(p){
q = p->next;
if(count%2 == 1){ //尾插
p->next = NULL;//断链,获得单个节点
r->next = p;
r = p;
pre->next = q; //保持原来链表联通 ,并更新结点
p = q;
}else{
pre = p; //更新节点
p = q;
}
count++;
}
return l1;
}
//原来表尾插法,l2头插法
LinkList discrete_one_two_2(LinkList l){//将a1,b1,a2,b2..拆分为a1-an, bn-b1
LinkList l2 = (LinkList)malloc(sizeof(LNode));
LNode* p = l->next,*r,*temp;
r = l;
l2->next = NULL;
while(p != NULL){
r->next = p;
r = p;
p = p->next;
if(p != NULL){//第二个结点非空插入l2
LNode* q = p->next;//保留后继
p->next = l2->next;
l2->next = p;
p = q;
}
// printf("fsd");
}
r->next = NULL;//尾结点next置为空
return l2;
}
void remove_repeat(LinkList l){//递增有序线性表去除相同元素
LNode* p = l->next,*q;
while(p->next){//判定条件不能改为p,防止下一行出现指针异常
q = p->next;
if(q->data == p->data){
p->next = q->next;
}else{
p = p->next;
}
}
}
//利用l1来当存储链表
LinkList mergeLinkList(LinkList l1,LinkList l2){//l1,l2递增有序合并为递减有序
LNode* n1 = l1->next,*n2 = l2->next,*p;
l1->next = NULL;
while(n1 && n2){
if(n1->data <= n2->data){
p = n1->next;
n1->next = l1->next;
l1->next = n1;
n1 = p;
}else{
p = n2->next;
n2->next = l1->next;
l1->next = n2;
n2 = p;
}
}
//通常只会有一个表非空,则判断只处理n2
if(n1){
n2 = n1;
}
while(n2){
p = n2->next;
n2->next = l1->next;
l1->next = n2;
n2 = p;
}
return l1;
}
int Mergelistl1_l2(LinkList l1,LinkList l2,LinkList l3){//l1,l2是单调递减合并这俩链表为l3单调递增且没有重复结点
LNode* la = l1->next,*lb = l2->next,*lc;
int count = 0;
l3 = (LinkList)malloc(sizeof(struct LNode));
l3->next = NULL;
while(la && lb){
count++;
lc = (LNode*)malloc(sizeof(struct LNode));
if(la->data > lb->data){
lc->data = la->data;
la = la->next;
}else if(la->data < lb->data){
lc->data = lb->data;
lb = lb->next;
}else{
lc->data = lb->data;
lb = lb->next;
la = la->next;
}
lc->next = l3->next;
l3->next = lc;
}
if(la)lb = la;
while(lb){
count++;
lc = (LNode*)malloc(sizeof(struct LNode));
lc->data = lb->data;
lb = lb->next;
lc->next = l3->next;
l3->next = lc;
}
return count;
}
LinkList mergeA_B(LinkList l1,LinkList l2){//用l1,l2公共元素产生c链表
LinkList l = (LinkList)malloc(sizeof(LNode));
LNode* r = l;
r->next = NULL;
while(l1->next && l2->next){
if(l1->next->data == l2->next->data){
LNode* n = (LNode*)malloc(sizeof(LNode));
n->next = NULL;
n->data = l1->next->data;
r->next = n;
r = n;
l1 = l1->next;
l2 = l2->next;
}else if(l1->next->data < l2->next->data){//数值小的结点后移重新进行比较
l1 = l1->next;
}else if(l1->next->data > l2->next->data){
l2 = l2->next;
}
}
return l;
}
void search_jiaoji(LinkList A,LinkList B){//A,B递增有序,求A,B交集
LNode* p = A->next,*q = B->next,*temp,*r;
A->next = NULL;
r = A;
while(p && q){
if(p->data == q->data){
temp = p->next;
r->next = p;
r = p;
p->next = NULL;
p = temp;
q = q->next;
}else if(p->data < q->data){
p = p->next;
}else if(p->data > q->data){
q = q->next;
}
}
}
int Is_childList(LinkList l1,LinkList l2){//判断l2是否是l1子序列
LNode* temp = l1->next,*p,*q;
p = l1->next;
q = l2->next;
while(p && q){
if(p->data == q->data){
p = p->next;
q = q->next;
}else{
q = l2->next;
p = temp->next;//比较l1后一个结点
temp = p->next;
}
}
if(q == NULL)return 1;
else return 0;
}
int isSymmetry(DList* list){//带头结点的循环双链表是否对称
DNode* n1 = list->first->next,*n2 = list->last; //n1第一个有效结点,n2最后一个有效结点
while(n1 != n2 && n2->next != n1){//一定要是n2->next != n1,不能写反
if(n1->data == n2->data){
n1 = n1->next;
n2 = n2->prior;
}else return 0;
}
return 1;
}
void merge_oneCycleList(List* list1,List* list2){//两循环单链表,将list2连接在list1后仍然循环
list1->last->next = list2->first->next;
list2->last->next = list1->first;
}
void del_min_onecycleList(List* list){//反复找循环单链表最小结点并删除
SNode* pre = list->first,*min = pre->next,*p = pre;
while(list->first->next != list->first){//表非空
while(p->next != list->first){//查遍一次循环
if(min->data > p->next->data){//寻找最小值
min = p->next;
pre = p;
}
p = p->next;
}
pre->next = min->next;
printf("%d ",min->data);
free(min);
pre = list->first;//更新结点
min = pre->next;
p = min;
}
free(list->first);
}
SNode* isCycleList(List* list){// 判断单链表是否有环
SNode* fast = list->first,*slow = list->first;
while(fast != NULL && fast->next != NULL){
slow = slow->next; //慢结点一次一步
fast = fast->next->next; //快结点一次两步
if(slow == fast)break;
}
if(fast == NULL || fast->next == NULL)return NULL; //表示没有循环
/*
a为头结点到循环入口节点距离
r为环长
x为循环入口节点到相遇之间距离
n为相遇时快结点在循环中绕的圈数
2(a+x) = a+n*r+x ==> a = n*r-x,当n == 1求循环入口
*/
SNode* p1 = list->first,*p2 = slow; //分别表示头结点 循环中相遇结点
while(p1 != p2){
p1 = p1->next;
p2 = p2->next;
}
return p1; //循环入口 结点
}
int Is_Symmestery(LinkList l,int n){//判断带头结点的链表是否中心对称
LNode* stack[100];
l = l->next;
int i = n/2,top = -1;
while(i>0){
stack[++top] = l;//前半段链表入队
l = l->next;
i--;
}
if(n % 2)l = l->next;//l指向后半段链表
while(l){
if(stack[top]->data == l->data){//一一出栈雨后把那段比较
top--;
l = l->next;
}else break;
}
if(top != -1)return 0;//非空说明不对称
return 1;
}
int Is_qian_N_duichen(SLinklist head,int n){ //不带头结点链表判断前n个结点是否中心对称
SNode* l = head;
int i = n/2;
while(i>0){
head = head->next;
i--;
}
if(n%2==1)head = head->next;
i = n/2;
while(i>0){
if(l == head){
l = l->next;
head = head->next;
}else{
return 1;//不对称
}
i--;
}
return 0;
}
int dc(LinkList head,int n){//判断带头结点的链表前n个节点是否中心对称
LinkList p;
char s[10];
int i=1;
int j;
p=head->next;
for(i=1;i<=n/2;i++){
s[i]=p->data;//前n/2各数据存入数组中
p=p->next;
}
j=i-1;
if(n%2==1){
p=p->next;//p指向后n/2开头
}
for(i=j;i>0;i--){
if(p->data==s[i]){
p=p->next;
}else break;
}
if(i!=0){
return 0;
}else{
return 1;
}
}
LNode* Fast_Find_Mid_Node(LinkList l){ //快速找到未知长度链表的中间节点
LNode* l1 = l; //利用快慢结点,快结点一次两步,慢的一步,当快的到末尾慢的到中间
while(l1->next != NULL){
if(l1->next->next != NULL){
l = l->next;
l1 = l1->next->next;
}else{
l1 = l1->next;
}
}
return l;
}
LinkList ji_ou_List(LinkList l){//将奇数结点偶数结点排在一起,且偶数结点再奇数节点后
if(l == NULL || l->next == NULL || l->next->next == NULL){
return l;
}
LNode* front = l,*l1 = l->next,*l3 = l1;//front标记头结点,l3标记偶列表头结点
while(l1 && l1->next){
l->next= l->next->next;
l1->next = l1->next->next;
l = l->next;
l1 = l1->next;
}
l->next = l3;//偶链表连在奇链表后
return front;
}
LinkList remove_end_n(LinkList l,int n){//删除链表倒数第n个结点
LNode* fast = l,*low = fast;
int i = 0;
while(i < n){
fast = fast->next;
if(fast == NULL)return l->next;//fast为最后一个结点删除头结点即可
i++;
}
while(fast->next){
low = low->next;
fast = fast->next;
}
low->next = low->next->next;//low->next即为倒数第n个结点
return l;
}
LinkList MergeTowList(LinkList l1,LinkList l2){//递归合并两个有序链表
if(l1 == NULL)return l2;//将非空结点返回
if(l2 == NULL)return l1;
if(l1->data <= l2->data){
l1->next = MergeTowList(l1->next,l2);
}else{
l2->next = MergeTowList(l1,l2->next);
}
}
void func(LinkList l,int n){//删除保存链表中第一次出现的结点删除其他绝对值与之相等的结点,数据大小小于n
LinkList r;
int temp;
int *p = (int *)malloc(sizeof(int) * (n+1));
for(int i = 0; i < n+1; i++){
*(p+i) = 0;//标记
}
while(l->next != NULL){
temp = l->next->data > 0 ? l->next->data : -l->next->data;
if(*(p+temp) == 0){
*(p+temp) = 1;
l = l->next;
}else{
r = l->next;
l->next = r->next;
free(r);
}
}
free(p);
}
void chang_list(LinkList l){//将s1,s2,s3.....sn,改为s1,sn,s2,sn-1...... ,将后半段结点逆置然后一次合并前半段和后半段
LNode* q,*p,*r,*s;//l为头结点
q = p = l;
while(q->next != NULL)//当q指向尾时p指向中间结点
{
p = p->next;
q = q->next;
if(q->next != NULL)q = q->next;
}
q = p->next;//p指向中间节点,q指向后半段首结点
p->next = NULL;//对后半段结点逆置
while(q != NULL){
r = q->next;
q->next = p->next;
p->next = q;
q = r;
}
s = l->next;//前半段第一个结点
q = p->next;//后半段结点第一个结点
p->next = NULL;
while(q != NULL){
r = q->next;//保存后半段结点的后继
q->next = s->next;//后半段插入前半段
s->next = q;
s = q->next;//指向前半段后继
q = r;//更新后半段结点
}
}
void reverse(int R[],int from,int to){// 对调
int i,temp;
for(i = 0; i < (to-from+1)/2; i++){
temp = R[from+i];
R[from+i] = R[to-i];
R[to-i] = temp;
}
}
void Converse(int R[],int n,int p){//将数组左移p个及将ab转换为ba
reverse(R,0,p-1);
reverse(R,p,n-1);
reverse(R,0,n-1);
}
void fun(LinkList l,LinkList l1,LinkList l2,LinkList l3){//将l中大写字母,数字,其他字符分别放在3链表
LNode* p;
l1 = (LinkList)malloc(sizeof(LinkList));
l2 = (LinkList)malloc(sizeof(LinkList));
l3 = (LinkList)malloc(sizeof(LinkList));
l = l->next;
while(l){
if(l->ch >= 'A' && l->ch <= 'Z'){
p->ch = l->ch;
l1->next = p;
l1 = p;
}else if(l->ch >= '0' && l->ch <= '9'){
p->ch = l->ch;
l2->next = p;
l2 = p;
}else{
p->ch = l->ch;
l3->next = p;
l3 = p;
}
}
l1->next = l2->next = l3->next = NULL;
}
链表的基本操作
于 2023-07-31 21:51:19 首次发布