C语言实现数据结构单链表的相关操作

    xiaoxiao2023-10-26  36

    #include <stdio.h> #include <stdlib.h> #include <malloc.h> #define FLAG -1 //停止输入的标志 typedef struct Node { int data; struct Node * next; }LNode,*LinkList; void show_List1(LinkList L); void CreateLinkList1(LinkList L); void CreateLinkList2(LinkList L); LNode *GetLinkList(LinkList L,int i); LNode *LocationLinkList(LinkList L,int x); void InsertLinkList(LinkList L,int i,int x); void DeleteLinkList(LinkList L,int i); int LengthLinkList(LinkList L); void reverse(LinkList L); void DelLink(LinkList L,int min,int max); LinkList MergeList(LinkList La,LinkList Lb); void main() { //创建头指针指向头结点 LinkList L = (LNode *)malloc(sizeof(LNode));//La,Lb,Lc; /*La = (LNode *)malloc(sizeof(LNode)); Lb = (LNode *)malloc(sizeof(LNode)); Lc = (LNode *)malloc(sizeof(LNode));*/ CreateLinkList2(L); show_List1(L); DelLink(L,4,8); show_List1(L); //La->next = Lb->next = Lc->next = NULL; //CreateLinkList1(L); /*printf("输入链表La:\n"); printf("输入链表Lb;\n"); CreateLinkList2(Lb); printf("合并后的链表:\n"); Lc = MergeList(La,Lb); show_List1(Lc);*/ //printf("\n%p",GetLinkList(L,2));//输出结点指针地址 //printf("\n%p",LocationLinkList(L,2));// /* InsertLinkList(L,2,99); show_List1(L); DeleteLinkList(L,5); show_List1(L); printf("%d",LengthLinkList(L));*/ /*reverse(L); printf("倒置后的链表:\n"); show_List1(L);*/ /*DelLink(L,3,7); printf("删除后的链表:\n"); show_List1(L);*/ } void show_List1(LinkList L) { LinkList p = L->next; printf("%d",p->data); p = p ->next; while(p != NULL) { printf("->%d",p->data); p = p->next; } printf("\n"); } void CreateLinkList1(LinkList L) //头插法 输出的是输入的逆序 { LinkList s; int x; scanf("%d",&x); while(x != FLAG) { /*s = L; s->data = x; L = (LNode *)malloc(sizeof(LNode)); L->next = s;*/ s = (LNode *)malloc(sizeof(LNode)); s->data = x; s->next = L->next; L->next = s; scanf("%d",&x); } } void CreateLinkList2(LinkList L) //尾插法 输出是输入的正序 { LinkList s,r; int x; scanf("%d",&x); r = L; //没写闪退 while(x != FLAG) { s = (LNode *)malloc(sizeof(LNode)); s->data = x; //r->next = s; //s->next = r->next; 出错误的原因是r->next中已经是新节点的地址了, //再把新节点地址赋值给它的指针域,会导致自己不断的指自己 不断 33333 //不妨先把r->next也就是NULL赋给新节点指针域,再将上一个指向新节点,这样就没问题了! //s->next = r->next; //第一种写法 r->next = s; r = s; scanf("%d",&x); } r->next = NULL;//第二种写法 先不管最后一个节点,最后再置为NULL } LNode *GetLinkList(LinkList L,int i)//按位置查找 { LinkList p; int j = 0; p = L; while(p != NULL && j < i) { p = p->next; j++; } return p; } LNode *LocationLinkList(LinkList L,int x) //按元素查找 { LinkList p; p = L->next; while(p != NULL && p->data != x) { p = p->next; } return p; } void InsertLinkList(LinkList L,int i,int x) { LinkList p,s; p = GetLinkList(L,i-1); if(p == NULL) { printf("插入失败!"); exit(1);//0 -1 1 一般0是正常退出 其他是异常退出 } else { s = (LNode*)malloc(sizeof(LNode)); s->data = x; s->next = p->next; p->next = s; } } void DeleteLinkList(LinkList L,int i)//删除第i个位置 p需要指向第i-1个位置 { LinkList q,p; p = GetLinkList(L,i-1); if(p == NULL) { printf("删除失败!"); exit(1); } else { if(p->next == NULL) { printf("删除失败!"); exit(1); } else { q = p->next; p->next = p->next->next; free(q); } } } int LengthLinkList(LinkList L) { int len = 0; LinkList p = L; while(p->next) { len++; p = p->next; } return len; } void reverse(LinkList L) { //节点指针p q //先把p指向首节点,再将头结点的指针域置为空 这样就出现一个p指向首节点的链表 //q指向与p相同的结点 然后p后移 //头结点的指针域中永远存放的是上一个结点的地址 // /*LinkList p,q; p = L->next; L->next = NULL; while(p) { q = p;//先将p赋值给q p = p->next; // p后移 q->next = L->next; // L->next = q; }*/ //设置了两个游标 p主要负责查看是否是最后一个元素 并且 将后面的元素串联起来 LinkList p,q; p = L->next; //记录下后面的所有元素 L->next = NULL;//方便设置第一个元素的指针域为0 while(p) // 是p不是p->next的原因 在于p->next会使最后一个元素无法倒置 { q = p; p = p->next;//这一步必须在 第三步的前面 否则将会失去后面的所有元素 q->next = L->next; //头结点中的指针域永远记录上一个元素的地址 L->next = q;//q当前所指元素指向上一个元素后 头结点记录下当前节点地址 } } void DelLink(LinkList L,int min,int max) { LinkList p,q,s; p = L->next; while((p != NULL) && (p->data <= min)) { q = p; p = p->next; } while((p != NULL) && (p->data < max)) { s = p; p = p->next; //删除结点 //q->next = p; free(s); } q->next = p; // } LinkList MergeList(LinkList La,LinkList Lb) { LinkList p,q,r,Lc; p = La->next; q = Lb->next; r = Lc = Lb; while(q&&p) { //p或者q中数据域小的那个应当让上一个结点指向 //并且应当把r指向小的那个结点 //进行完上叙操作后,数据域小的那个应当将p或者q后移 if(p->data >= q->data) { r->next = q; r = r->next; q = q->next; } else { r->next = p; r = r->next; p = p->next; } } if(q) { //说明后面还有 r->next = q; } else { r->next = p; } free(La); return Lc; }
    最新回复(0)