/* 构造一个带头节点的空链表1.1为单链表的指针、头指针可以标志一个 确定的单链表,算法中1前的"&"表示该变量是指针的指针的类型,实现时用*表示 */ #include <iostream> using namespace std; /* 描述一个单链表 */ typedef struct node { int data; //定义存储整形数据 struct node *next; //定义存储下一个数据位置的指针 }node, *linkList; /* 首先初始化一个链表 */ int Initlist (linkList &a) { if ( (a = (node*)malloc(sizeof(node))) == NULL) return 0; else { a->next =NULL; return 1; } } /* 建立一个链表。类似于往栈中存放数据。p为动态指针,始终指向未分配数据的最顶端。 head为链表的头指针,头指针值指向链表中第一个元素的存储地址。 */ node* Create() { node *head = (node*)malloc(sizeof(node));//定义指向结构体的头指针 node *p; node *s; int x; int cycle = 1; p = head; //把头指针指向p while(cycle) { cout<<"Please input the data"<<endl; cin>>x; //每输入一次数据 if(x!=0) { s = (node*)malloc(sizeof(node));//分配一个内存地址 s->data = x; //把输入的数据传入到s所指向的地址中去 cout<<x; p->next = s; //把分配的(指向该数据x的)内存地址保存到上一个数据的next指针中去 p = s; //让指针p重新指向当前位置 } else cycle = 0; } head = head->next; //head p->next = NULL; //把最后一个数据的指针赋值为NULL cout<<head->data;//最先传进去的值 return (head);//返回 } /* 单链表测长,掌握结构体作为形参的传参方式 */ int length(struct node *head) { int n = 0; struct node *p; p = head; while(p!=NULL) { p = p->next; n++; } return (n); } /* 单链表打印 */ void prient(struct node *head) { struct node *p; int n; n = length(head);//获得链表的长度 p = head; if(head != NULL) while(p!=NULL) { cout<<p->data; p=p->next; } } /* 单链表删除一个节点.分为两种情况,一是删除的是头结点;二是删除节点 */ node* deleteNode(struct node *head,int num) //num为要删除的链表中的元素 { struct node *p; struct node *pFollow; p = head ; //找到需要删除的那个数,并且需要在链表的长度内 while(num!=p->data && p->next !=NULL) { pFollow = p; p = p->next; } if(p->data ==num) { //如果删除的为第一个节点 if(p ==head) { head = p->next; free(p); } //否则 else { pFollow->next = p->next; free(p); } } return (head); } /* 单链表的插入 插入算法有多种,比如(1)在某个数据之后插入一个新的元素 (2)在第i-1和i个数据之后插入一个新的元素 (3)在递增/减有序表中插入一个新的元素,使得生成的长度为n+1的表仍然是有序的 这里只是介绍第(2)中算法 */ node* InsertList(struct node *head, int i, int elem) // i 要插入的元素的位置;elem 要插入的元素 { struct node *p; struct node *s; s = (node*)malloc(sizeof(node));//生成一个新的节点 p = head; int j = 0;//计数器 //如果插入的是在头节点 while(p->next != NULL && i != j) { p = p->next; //指向下一个节点 j++; } //找到要插入的元素的位置 s->data = elem; //将新的元素插入到数据区域中 s->next =p->next;//将上一个节点指针赋值到新的指针区域 p->next =s; return (head); } /* 单链表的清空 */ node* CleanList(struct node* head) { struct node* p; p = head; while(p->next!= NULL) { p= p->next; free(p); } return (head); } /* 单链表的排序。将所有的数据按有大到小的顺序重新排列,并从新输出 */ node* SortList(struct node* head) { struct node *p; int temp; p = head; //获得链表的长度 int n = length(head); if(head ==NULL || head->next ==NULL) { return head; } for(int i = 1;i<n;i++) //n-1次 { p = head; for (int j =0;j<n-i;j++) //n-i次 { if( (p->next)->data < p->data) //后者大于前者 { temp = p->data; //交换值 p->data = (p->next)->data; (p->next)->data = temp; } p = p->next; //指向下一个地址 } } return (head); } /* 单链表的逆置 */ node* InverseList(struct node* head) { struct node *p; p = head; int temp; int n = length(head); for (int i = 1;i<n;i++) //n-1次 { p = head; for(int j = 0;j<n-i; j++) { temp = p->data; p->data = p->next->data; p->next->data = temp; p = p->next; } } return (head); } void main() { struct node *testNode; struct node *newNode; struct node *tnewNode; struct node *knewNode; //创建一个链表 testNode = Create(); cout<<"输出该结构体数组的长度"<<endl; cout<<length(testNode)<<endl; prient(testNode); //删除一个元素 newNode=deleteNode(testNode,5); cout<<endl; prient(newNode); //插入一个新的元素 InsertList(newNode, 3, 100); cout<<endl; prient(newNode); //排序(有小到大) tnewNode=SortList(newNode); cout<<endl; prient(tnewNode); //逆序输出 knewNode=InverseList(tnewNode); cout<<endl; prient(knewNode); }