1.实现一个单链表的定义,生成,长度计算和元素的显示。
#include"iostream"
using namespace std;
typedef struct student{
int data;
student *next;
student(int x) :data(x), next(NULL){}
}ListNode;
/*
生成一个单链表
*/
ListNode* creatList(){
ListNode *head ,*cur, *temp;
int x, cycle = 1;
head = (ListNode*)malloc(sizeof(ListNode));//给head节点分配一个ListNode大小的内存空间
cur = head;
while (cycle){//输入数据已0作为链表的结束
cout << "please input data:" << endl;
scanf("%d", &x);
if (x){
temp = (ListNode*)malloc(sizeof(ListNode));
temp->data = x;
cur->next = temp;
cur = temp;
}
else{
cycle = 0;
}
}
head = head->next;
cur->next = NULL;
return head;
}
/*
求链表的长度
*/
int listLength(ListNode *head){
ListNode *temp = NULL;
temp = head;
int len = 0;
while (temp){
temp = temp->next;
len++;
}
return len;
}
/*
打印出链表的长度及元素
*/
void printList(ListNode *head){
ListNode *temp;
int len;
len = listLength(head);
cout << "There are " <<len<< " records are: " << endl;
temp = head;
while (temp){
cout << temp->data <<" ";
temp = temp->next;
}
}
int main(){
ListNode *head = creatList();
printList(head);
system("pause");
return 0;
}
运行结果如下图所示:
2.增加删除节点功能
此时分三种情况,(1)当删除的是第一个节点时的情况,(2)当删除时中间节点的情况,包括最后一个节点的情况,(3)当需要删除的节点不在此链表中时,则直接返回原链表。
当时第一种情况时,只需要将指向第一个节点的指针指向下一个节点即可;当第二种情况时,则之前需要保存当前删除节点的前一个节点,让这个节点指向删除节点的下一个节点即可。
代码如下:
/*
删除节点
*/
ListNode* delListNode(ListNode *head,int num){
ListNode *pre, *cur;
pre = NULL;
cur = head;
while (num != cur->data && cur->next){
pre = cur;
cur = cur->next;
}
if (num == cur->data){
if (cur == head){
head = cur->next;
free(cur);
}
else{
pre->next = cur->next;
free(cur);
}
}
else{
cout << num << " could not been found" << endl;
}
return head;
}
int main(){
ListNode *head = creatList();
printList(head);
ListNode *h2 = delListNode(head, 5);
printList(h2);
system("pause");
return 0;
}
现象如下所示:
3.增加链表排序功能
代码如下:
/*
排序,使用冒泡法进行升序排序
*/
ListNode* sortList(ListNode *head){
ListNode *cur;
if (!head || head->next == NULL) return head;
int len = listLength(head);
int temp = 0;
cur = head;
for (int i = 1; i < len; i++){//只需进行len-1次for循环
cur = head;
for (int j = 0; j < len - i; j++){//每执行一次for就可以将最大的数移到后面到正确位置,所以每次只需要进行len-i次for循环
if (cur->data > cur->next->data){
temp = cur->data;
cur->data = cur->next->data;
cur->next->data = temp;
}
cur = cur->next;
}
}
return head;
}
int main(){
ListNode *head = creatList();
printList(head);
//ListNode *h2 = delListNode(head, 5);
//printList(h2);
ListNode *h3 = sortList(head);
printList(h3);
system("pause");
return 0;
}
现象如下所示:
4.增加插入节点功能
假设所给链表是已经按升序排好序的链表,给定一个值,将其插入到链表中,使链表仍然是有序的
插入时分三种情况:
(1)当插入节点值是最小的,则直接放在链表的最前面;
(2)当插入节点值既不最大也不最小,则放在链表中的正确位置上;
(3)当插入节点值时最大的,则放在链表的最后。
代码如下:
/*
插入节点
*/
ListNode* insertListNode(ListNode *head, int num){
ListNode *temp,*pre, *cur;
temp = (ListNode*)malloc(sizeof(ListNode));
temp->data = num;
cur = head;
pre = NULL;
while (temp->data > cur->data && cur->next){
pre = cur;
cur = cur->next;
}
if (temp->data <= cur->data){
if (cur == head){
temp->next = cur;
head = temp;
}
else{
pre->next = temp;
temp->next = cur;
}
}
else{
cur->next = temp;
temp->next = NULL;
}
return head;
}
int main(){
ListNode *head = creatList();
printList(head);
//ListNode *h2 = delListNode(head, 5);
//printList(h2);
ListNode *h3 = sortList(head);
printList(h3);
ListNode *h4 = insertListNode(h3, 6);
printList(h4);
system("pause");
return 0;
}
现象如下图所示,三种情况的现象图都已给出。
4.增加链表的逆置功能
思路:每次保存三个节点pre,cur,next,改变前两个节点pre和cur的指针指向,之后重新保存三个节点,此时cur变成pre,next变成cur,next->next变成next。
代码如下:
/*
链表逆置
*/
ListNode* reverseList(ListNode *head){
ListNode *pre, *cur,*next;
if (!head || head->next == NULL) return head ;
pre = head;
cur = pre->next;
while (cur){
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
head->next = NULL;
head = pre;
return head;
}
int main(){
ListNode *head = creatList();
printList(head);
//ListNode *h2 = delListNode(head, 5);
//printList(h2);
/*ListNode *h3 = sortList(head);
printList(h3);
ListNode *h4 = insertListNode(h3, 6);
printList(h4);*/
ListNode *h5 = reverseList(head);
printList(h5);
system("pause");
return 0;
}
现象如下图所示: