升序链表的基本操作
来源:互联网 发布:淘宝店设置信用卡支付 编辑:程序博客网 时间:2024/05/19 02:45
// List1.cpp : Defines the entry point for the console application.///* C语言下的升序链表的基本操作 List1.cpp ------------------------------------- 作者: Software Engineering @ HIT 1093710210 Alex 时间: 2010.9.10 -------------------------------------*///黄虎杰院长在数据结构基础与算法课上留的一个小练习。。。好几天了,一直没写,感觉不会太难,没想到一写还真是把自己整的挺蒙的,还要多练啊//不过写链表的过程中学到了很多经验。。不要迷信网络。。感觉好乱。。还是准备一张白纸一支笔。。自己画得明白= =#include "stdafx.h"#include "stdio.h"#include "stdlib.h"struct List{ int data; struct List *next;};void menu();struct List *Create(struct List *h) ; //创建和插入升序链表void Display(struct List *h); //输出链表信息struct List *Delete_all(struct List *h); //删除整个链表struct List *Delete(struct List *h , int xdata) ; //删除链表中结点struct List *Search(struct List *h , int xdata) ; //查找某节点位置,本例中返回了其地址struct List *Revers(struct List *h) ; //实现链表的逆序int main(int argc, char* argv[]){ int choice,i =0; struct List *position,*MyList = NULL; int xdata; menu(); while (1) { printf("请输入操作: "); scanf("%d",&choice); switch (choice) { case 1: printf("Please input the node: /n"); MyList = Create( MyList); break; case 2: printf("Please input the node you want to delete: /n"); scanf("%d",&xdata); MyList = Delete( MyList,xdata); break; case 3: printf("Please input the node you want to locate: /n"); scanf("%d",&xdata); position = Search(MyList,xdata); printf("the node position is %d",position); break; case 4: Display(MyList); break; case 5: MyList = Revers( MyList); printf("The links reversed is :/n"); Display(MyList); break; case 6: MyList = Delete_all(MyList); printf("Link deleted ! /n"); break; default: printf("wrong!"); } } return 0;}void menu(){ printf("单向升序链表的操作/n"); printf("-----------------------------------------/n"); printf("1 -> 创建升序链表链表或插入节点升序链表中/n"); printf("2 -> 删除链表中的某个节点/n"); printf("3 -> 返回某个节点的地址指针/n"); printf("4 -> 输出线性链表/n"); printf("5 -> 实现单向链表逆序/n"); printf("6 -> 删除整个线性表/n");}/*函数功能:升序输入链表函数函数参数:结构体指针返回值 : 结构体指针*/struct List *Create(struct List *h){ struct List *newpr = NULL; struct List *temp = h; struct List *flag = NULL; int data; newpr = (struct List *)malloc(sizeof (struct List)); if (newpr == NULL) //用于检查是否申请动态空间成功 { printf("memory error"); exit(0); } scanf("%d",&data); newpr->data = data; newpr->next = NULL; if (h == NULL) h = newpr; else { while (temp->next != NULL && temp->data <= data ) //老师上课用的<,我感觉还是应该用<=这样可以解决重复输入相同data无效的问题 { flag = temp; //flag用于记录合适的插入点前的位置 temp = temp->next; } if (temp->data >data) //用于检查时否在两个值之间,可以看出是否到了链表的末尾 { if (temp == h) //说明在表头前插入数据,产生新的表头 { newpr->next = h ; h = newpr ; } else { temp = flag; //把当前的位置前移一下,移到插入点前面 newpr->next = temp->next; temp->next = newpr; } } else //在表末插入 { temp->next =newpr; } } return h;}/*函数功能:输出线性表函数参数:结构体指针返回值 : void*/void Display(struct List *h){ struct List *p = h; int counter = 1; printf("Position: Data /n"); while (p != NULL) { printf(" %d " ,counter); printf(": %d/n", p->data ); counter++; p = p->next; }}/*函数功能:删除某个结点函数参数:结构体指针,要删除节点数据int返回值 : 结构体指针*/struct List *Delete(struct List *h , int xdata){ struct List *temp = h; struct List *flag = h; if ( h == NULL) { printf("no link !"); return (h); } while (temp->data != xdata && temp->next !=NULL) { flag = temp; temp = temp->next; } if (xdata == temp->data) //检查是到了末尾还是已经找到相应节点 { if (temp == h) //首节点的情况 { h = temp->next; } else { flag->next=temp->next; } free (temp); } else printf("NO NODE!/n"); return h;}/*函数功能:返回某节点的地址函数参数:结构体指针,要查找节点数据int返回值 : 结构体指针*/struct List *Search(struct List *h , int xdata){ struct List *temp = h; if ( h == NULL) { printf("no link !"); return (h); } while (temp->data != xdata && temp->next !=NULL) { temp = temp->next; } if (xdata == temp->data) //检查是到了末尾还是已经找到相应节点 return temp; else printf("NO Location!/n"); return temp;}/*函数功能:单向链表的逆序函数参数:结构体指针返回值 : 结构体指针*/struct List *Revers(struct List *h){ struct List *back,*p,*newhead = NULL; p = h; while ( p != NULL) { back = p->next; //记录当前节点的下一位置,以防链表丢失 p->next = newhead ; //当前节点开始指向前一个节点,此时的newhead初始化一定为NULL newhead = p ; //newhead指针紧跟着p向后移,一直到最后p指向NULL了,此时newhead为逆序的首结点 p= back; //找到下一个节点 } return newhead;}//感受:从网上看了一个,分明是弄错指针p后移时,没有记录下一节点的位置,造成链表的断开//他的做法是 back = p;// p->next = newhead ;// newhead = p ;// p= back->next; 这样的话表面上是back记录了下一个节点,实际上他指向的P的next已经被修改为NULL,使得最后一行语句无效struct List *Delete_all(struct List *h){ struct List *temp = NULL; while (h!= NULL) { temp = h; h=temp->next; free(temp); } return h;}