数据结构之单链表
单链表相对于顺序表来说拥有可以减少使用空间,可以更快速的对表中数据进行插入与删除的优点,而对于顺序表,查找一个元素的时间复杂度仅仅为O(1),然而单链表却需要遍历寻找。
以下是我写的单链表,功能不知完全不完全,希望大家都有一些收获吧。
/************************************************************************/
/* 以下是关于线性表链接存储(单链表)操作的14种算法 */
/* 1.初始化线性表,即置单链表的表头指针为空 */
/* 2.创建线性表,此函数输入零终止读取数据*/
/* 3.打印链表,链表的遍历*/
/* 4.销毁线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
/* 5.返回单链表的长度 */
/* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
/* 7.查找第i个元素,若为查找到输出提示语句,否则返回查找值*/
/* 8.查找第i个元素的前驱。*/
/* 9.查找第i个元素的后继。*/
/* 10.确定一个数的位置,若找到输出位置所在,找不到,返回提示语句。*/
/* 11.在链表中插入一个元素*/
/* 12.在链表中删除一个元素*/
/* 13.合并两个有序的链表.*/
/* 14.给定一个数,看是否可以在链表中删除。*/
FISRT:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -2 typedef int elemType;
这里是一些规定,以及需要用到的头文件。
接下来就要来看单链表的储存结构:
typedef struct Node { elemType e; struct Node *next; };
/* 1.初始化线性表,即置单链表的表头指针为空 */
void InitList(Node **head) { *head=NULL; cout<<"get a empty list"<<endl; }
/* 2.创建线性表,此函数输入零终止读取数据*/
void createList(struct Node **head) { struct Node *t,*w; int shu; *head = NULL; cout<<"请输入一个数:(输入零终止输入) :"; cin>>shu; while(shu!=0) { t=(Node *)malloc(sizeof(struct Node)); t->e=shu; t->next=NULL; //由于没有头结点,需要判断链表首结点是否为空,若为空,就插入到首节点,不为空则插入已有节点之后。 if(*head==NULL) { *head=t; } else { w->next=t; } w=t; cout<<"请输入一个数:(输入零终止输入) :"; cin>>shu; } }
/* 3.打印链表,链表的遍历*/
void visit(struct Node *head) { if(head==NULL) cout<<"not exit"<<endl;//链表为空 else//链表不为空 { while(head) { if(head->next!=NULL) cout<<head->e<<" "; else cout<<head->e<<endl;//最后一个后面没有空格,比较严谨 head=head->next; } } }
/* 4.销毁线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
void Destroy(struct Node *head) { Node *p; while(head!=NULL) { p=head; head=head->next; free(p); } cout<<"finish"<<endl; }
/* 5.返回单链表的长度 */
int listlength(Node *head)//遍历的方法求长度,也可以边创建链表,边计算长度。 { int len=0; while(head!=NULL) { head=head->next; len++; } return len; }
/* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
elemType isEmptyList(Node *head) { if(head == NULL) { cout<<"isEmptyList函数执行,链表为空\n"; return 1; } cout<<"isEmptyList函数执行,链表非空\n"; return 0; }
/* 7.查找第i个元素,若为查找到输出提示语句,否则返回查找值*/
elemType getelem(Node *head,int pos) { int i=0; if(pos<1) cout<<"please check input"<<endl; if(head==NULL)//表为空 { cout<<"not exit"<<endl; exit(ERROR); } while(head!=NULL) { ++i; if(i==pos) { break; } else { head=head->next; } } if(i<pos) { cout<<"pos is larger than i,please check intput"<<endl; } return head->e; }
/* 8.查找第i个元素的前驱。*/
elemType priorelem(Node *head,int pos) { int i=0; if(pos<1) cout<<"please check input"<<endl; if(head==NULL) { cout<<"not exit"<<endl; exit(ERROR); } while(head!=NULL) { ++i; if(i==pos-1) { break; } else { head=head->next; } } if(i<pos-1) { cout<<"pos is larger than i,please check intput"<<endl; } return head->e; }
/* 9.查找第i个元素的后继。*/
elemType nextelem(Node *head,int pos) { int i=0; if(pos<1) cout<<"please check input"<<endl; if(head==NULL) { cout<<"not exit"<<endl; exit(ERROR); } while(head!=NULL) { ++i; if(i==pos+1) { break; } else { head=head->next; } } if(i<pos+1) { cout<<"pos is larger than i,please check intput"<<endl; } return head->e; }
/* 10.确定一个数的位置,若找到输出位置所在,找不到,返回提示语句。*/
void locateelem(Node *head,int pos) { if(head==NULL) cout<<"not exit"<<endl; else { int i=0,flag=0; while(head!=NULL) { ++i; if(pos==head->e) { flag=1; break; } head=head->next; } if(flag==1)cout<<"元素"<<pos<<"的位置为:"<<i<<endl; else cout<<"该链表中无此元素"<<endl; } }
/* 11.在链表中插入一个元素*/
void listinsert(Node **head,int w,int n) { struct Node *add; struct Node *jihead; int count=1;//计数器 jihead = *head; add = (Node* )malloc(sizeof(Node)); add->e = n; add->next = NULL; if(*head == NULL)//如果表中无数据就插入在表头 { *head=add; } if(w == 1)//在第一个位置插入数据 { add->next = *head; *head = add; return ; } while(jihead!=NULL) { count++; if(count==w) { add->next=jihead->next; jihead->next=add; return ; } jihead=jihead->next; } jihead->next=add;//最后也没找到位置,就插在末尾。 }
/* 12.在链表中删除一个元素*/
void listdelete(Node **head,int n) { struct Node *dele,*jihead; jihead=*head; int count=1;//依旧还是计数器 if(*head==NULL) { cout<<"链表为空"<<endl; } if(n==1)//删除第一位 { dele=*head; *head=(*head)->next; free(dele); } while(jihead!=NULL) { count++; if(count==n) { dele=jihead->next; jihead->next=jihead->next->next; free(dele); } jihead=jihead->next; } }
/* 13.合并两个有序的链表.*/
struct Node* SortedMerge(struct Node* a, struct Node* b)//两个单调不递减的有序序列 { struct Node* result = NULL; if(a == NULL) return b; else if(b == NULL) return a; /*Pick either a or b, and recur */ if(a->e <= b->e) { result = a; result->next = SortedMerge(a->next, b);//递归 } else { result = b; result->next = SortedMerge(a, b->next); } return (result); }
/* 14.给定一个数,看是否可以在链表中删除。*/
void listdrop(Node **head,int pos) { struct Node *del,*jihead; jihead=*head; if((*head)->e==pos) { del=*head; *head=(*head)->next; free(head); } else { while(jihead!=NULL) { if(jihead->next->e==pos) { del=jihead->next; jihead->next=jihead->next->next; free(del); return; } jihead=jihead->next; } } }
主函数:
int main() { struct Node *p1; struct Node *p2; struct Node *p3; createList(&p1); visit(p1); int n; cin>>n; listdrop(&p1,n); visit(p1); createList(&p2); visit(p2); p3=SortedMerge(p1,p2); //cout<<"length: "<<listlength(p)<<endl; //visit(p3); //cout<<"---------------"<<endl; //cout<<"查找第i位元素: "<<getelem(p,2)<<endl; //cout<<"查找第i位元素前驱: "<<priorelem(p,2)<<endl; //cout<<"查找第i位元素后继: "<<nextelem(p,2)<<endl; //locateelem(p,2); //listinsert(&p,3,99); //visit(p); //listdelete(&p,4); //visit(p); //InitList(&p); //Destroy(p); //visit(p); return 0; }
新手博文,如有缺憾,还望指教。