单向链表

来源:互联网 发布:查找质数的算法 编辑:程序博客网 时间:2024/05/24 06:00

1、静态链表

class Link{public:int age;char name[20];Link *next;};int main(){//声明3个节点对象,表明链表中有3个元素Link lnk[3];//声明头指针节点和一个临时的指针节点Link *head, *p;//对节点赋值lnk[0].age = 21;strcpy_s(lnk[0].name, "张三");lnk[1].age = 23;strcpy_s(lnk[1].name, "李四");lnk[2].age = 25;strcpy_s(lnk[2].name, "王五");//设置头节点(头节点通常指向链表的第一个元素)head = &lnk[0];//对节点中的next指针赋值,将其串联成链表lnk[0].next = &lnk[1];lnk[1].next = &lnk[2];//最后一个节点中没有其他节点指针了,所以为NULLlnk[2].next = NULL;//把头节点赋给临时节点p = head;//遍历链表while(p){cout<<p->age<<"  "<<p->name<<endl;//每次循环,p都会发生变化,这就是要把head赋给p的原因//要是直接用head遍历,那后面再要用到头节点head的时候,就找不到链表首地址了p = p->next;}return 0;}

2、动态链表

(1)动态创建

class Link{public:int age;char name[20];Link *next;};//头节点Link *Head = NULL;Link *Create(){//p1作为新节点指针,p2作为旧节点指针Link *p1, *p2;//先动态开辟一个新节点p1 = new Link;//设置链表的初始状态Head = p2 = p1;cout<<"输入年龄(0退出):";cin>>p1->age;if (p1->age != 0){cout<<"输入姓名";cin>>p1->name;}else{delete p1;Head = p2 = p1 = NULL;return Head;}while (p1->age != 0){//每次循环,p1都会创建一个新的节点,在创建新节点之前,要把旧节点保存到p2p2 = p1;p1 = new Link;cout<<"输入年龄(0退出):";cin>>p1->age;if (p1->age != 0){cout<<"输入姓名";cin>>p1->name;}//把新创建的节点保存到p2的指针域,这样做是因为p2负责保存旧节点,p1负责创建新节点,p2->next保存新创建的节点,环环相扣//因为一开始p,p1,Head都是指向相同的地址,而且Head的地址一直不会改变,所以利用Head头指针就可以遍历整个链表p2->next = p1;}//释放p1delete p1;//把p2的指针域置空,但是p2本身是有数据的,是尾节点p2->next = NULL;return Head;}


(2)显示链表

void Show(Link *head){while (head){cout<<head->age<<"  "<<head->name<<endl;head = head->next;}}

(3)链表长度

int Length(Link *p){int n = 0;while(p){n++;p = p->next;}return n;}

(4)删除链表

void Delete(Link *lst, char *name){Link *next;Link *pre;//第一个节点即为要删除的目标if (strcmp(lst->name,name) == 0){//保存第一个节点的指针域,把下一个节点作为头节点next = lst->next;//删除目标节点delete lst;//更新一下全局的头指针::Head = next;return;}while (lst){if (strcmp(lst->name,name) == 0){//目标是最后一个链表元素if (lst->next == NULL){//pre->next是当前的节点lst,因为是最后一个节点,所以指针域赋空pre->next = NULL;//让lst指向前一个节点lst = pre;//删除节点,这个节点就是之前的lstdelete pre->next;return;}else{//把当前节点lst的下一个节点赋值给它的上一个节点的下一个节点,意思就是断开当前节点lst与链表的关系pre->next = lst->next;//记录当前节点地址,以便后面删除next = lst;//让lst指向前一个节点lst = pre;//释放原先lst所占的内存delete next;return;}}//记录链表循环的上一次指向地址pre = lst;lst = lst->next;}}

(5)插入节点

void Insert(Link *lst, Link *insertData, int pos){assert(lst);assert(insertData);Link *pre;//如果指定位置是0或1或小于0,默认插入到第一个位置if (pos >= 0 && pos <= 1){insertData->next = lst;::Head = insertData;return;}//在链表的中间和末尾插入int n = Length(lst);int npos = 1;while (lst){//末尾插入if (pos > n){while (lst){if (lst->next == NULL){insertData->next = NULL;lst->next = insertData;return;}lst = lst->next;}return;}//中间插入if (npos == pos){//把lst添加新节点的next域insertData->next = lst;//现在lst是原来它前面的一个节点lst = pre;//新节点添加到链表lst->next = insertData;return;}pre = lst;lst = lst->next;npos++;}}

(6)测试链表

int main(){Create();Delete(Head,"zhangsan");Link *pNode = new Link;pNode->age = 27;strcpy_s(pNode->name,"Hello");Insert(Head,pNode,1);Show(Head);cout<<"链表长:"<<Length(Head)<<endl;return 0;}




原创粉丝点击